Merge inbound to mozilla-central. a=merge
authorCsoregi Natalia <ncsoregi@mozilla.com>
Fri, 27 Jul 2018 00:58:11 +0300
changeset 483718 8f2f847b2f9d
parent 483589 3f362dfcc160 (current diff)
parent 483717 2be44821f02f (diff)
child 483735 3b1b9fcf8b96
child 483770 98884f98717d
push id9719
push userffxbld-merge
push dateFri, 24 Aug 2018 17:49:46 +0000
treeherdermozilla-beta@719ec98fba77 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone63.0a1
first release with
nightly linux32
8f2f847b2f9d / 63.0a1 / 20180726220124 / files
nightly linux64
8f2f847b2f9d / 63.0a1 / 20180726220124 / files
nightly mac
8f2f847b2f9d / 63.0a1 / 20180726220124 / files
nightly win32
8f2f847b2f9d / 63.0a1 / 20180726220124 / files
nightly win64
8f2f847b2f9d / 63.0a1 / 20180726220124 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to mozilla-central. a=merge
browser/app/profile/firefox.js
gfx/src/nsThemeConstants.h
js/src/builtin/SIMD.cpp
js/src/builtin/SIMD.h
js/src/builtin/SIMDConstants.h
js/src/jit-test/lib/simd.js
js/src/jit-test/tests/SIMD/anyall.js
js/src/jit-test/tests/SIMD/binary-arith.js
js/src/jit-test/tests/SIMD/bool32x4-arith.js
js/src/jit-test/tests/SIMD/bool32x4-const.js
js/src/jit-test/tests/SIMD/bug1109911.js
js/src/jit-test/tests/SIMD/bug1121299.js
js/src/jit-test/tests/SIMD/bug1123631.js
js/src/jit-test/tests/SIMD/bug1130845.js
js/src/jit-test/tests/SIMD/bug1241872.js
js/src/jit-test/tests/SIMD/bug1248503.js
js/src/jit-test/tests/SIMD/bug1273483.js
js/src/jit-test/tests/SIMD/bug1296640-gc-args.js
js/src/jit-test/tests/SIMD/bug1303780-gc-args.js
js/src/jit-test/tests/SIMD/bug1435317.js
js/src/jit-test/tests/SIMD/bug953108.js
js/src/jit-test/tests/SIMD/check.js
js/src/jit-test/tests/SIMD/compare.js
js/src/jit-test/tests/SIMD/complex-4.js
js/src/jit-test/tests/SIMD/convert.js
js/src/jit-test/tests/SIMD/float32x4-binary-arith.js
js/src/jit-test/tests/SIMD/getters.js
js/src/jit-test/tests/SIMD/inline-missing-arguments.js
js/src/jit-test/tests/SIMD/load.js
js/src/jit-test/tests/SIMD/nursery-overflow.js
js/src/jit-test/tests/SIMD/recover.js
js/src/jit-test/tests/SIMD/replacelane.js
js/src/jit-test/tests/SIMD/saturate.js
js/src/jit-test/tests/SIMD/select.js
js/src/jit-test/tests/SIMD/shift.js
js/src/jit-test/tests/SIMD/shuffle.js
js/src/jit-test/tests/SIMD/splat.js
js/src/jit-test/tests/SIMD/store.js
js/src/jit-test/tests/SIMD/swizzle.js
js/src/jit-test/tests/SIMD/uconvert.js
js/src/jit-test/tests/SIMD/unary.js
js/src/jit-test/tests/SIMD/unbox.js
js/src/jit-test/tests/asm.js/bug1201124-simd-proxy.js
js/src/jit-test/tests/asm.js/simd-fbirds.js
js/src/jit-test/tests/asm.js/simd-mandelbrot.js
js/src/jit-test/tests/asm.js/testBug1099216.js
js/src/jit-test/tests/asm.js/testSIMD-16x8.js
js/src/jit-test/tests/asm.js/testSIMD-8x16.js
js/src/jit-test/tests/asm.js/testSIMD-bitcasts.js
js/src/jit-test/tests/asm.js/testSIMD-load-store.js
js/src/jit-test/tests/asm.js/testSIMD.js
js/src/jit/EagerSimdUnbox.cpp
js/src/jit/EagerSimdUnbox.h
js/src/tests/non262/SIMD/ToSource.js
js/src/tests/non262/SIMD/binary-operations.js
js/src/tests/non262/SIMD/browser.js
js/src/tests/non262/SIMD/bug1023145.js
js/src/tests/non262/SIMD/bug953270.js
js/src/tests/non262/SIMD/check.js
js/src/tests/non262/SIMD/comparisons.js
js/src/tests/non262/SIMD/constructors.js
js/src/tests/non262/SIMD/conversions.js
js/src/tests/non262/SIMD/float64x2-arithmetic.js
js/src/tests/non262/SIMD/load-floats.js
js/src/tests/non262/SIMD/load-int16x8.js
js/src/tests/non262/SIMD/load-int32x4.js
js/src/tests/non262/SIMD/load-int8x16.js
js/src/tests/non262/SIMD/load-sab-buffer-compat.js
js/src/tests/non262/SIMD/load-unsigned-integers.js
js/src/tests/non262/SIMD/minmax.js
js/src/tests/non262/SIMD/replaceLane.js
js/src/tests/non262/SIMD/select-bitselect.js
js/src/tests/non262/SIMD/shell.js
js/src/tests/non262/SIMD/shifts.js
js/src/tests/non262/SIMD/splat.js
js/src/tests/non262/SIMD/store.js
js/src/tests/non262/SIMD/swizzle-shuffle.js
js/src/tests/non262/SIMD/toString.js
js/src/tests/non262/SIMD/typedobjects.js
js/src/tests/non262/SIMD/unary-operations.js
taskcluster/docker/funsize-update-generator/requirements.txt
testing/web-platform/meta/MANIFEST.json
testing/web-platform/meta/web-animations/timing-model/timelines/update-and-send-events.html.ini
third_party/rust/itertools-0.6.5/.cargo-checksum.json
third_party/rust/itertools-0.6.5/.travis.yml
third_party/rust/itertools-0.6.5/Cargo.toml
third_party/rust/itertools-0.6.5/LICENSE-APACHE
third_party/rust/itertools-0.6.5/LICENSE-MIT
third_party/rust/itertools-0.6.5/Makefile
third_party/rust/itertools-0.6.5/README.rst
third_party/rust/itertools-0.6.5/benches/bench1.rs
third_party/rust/itertools-0.6.5/benches/extra/mod.rs
third_party/rust/itertools-0.6.5/benches/extra/zipslices.rs
third_party/rust/itertools-0.6.5/benches/tuple_combinations.rs
third_party/rust/itertools-0.6.5/benches/tuples.rs
third_party/rust/itertools-0.6.5/custom.css
third_party/rust/itertools-0.6.5/examples/iris.data
third_party/rust/itertools-0.6.5/examples/iris.rs
third_party/rust/itertools-0.6.5/src/adaptors/mod.rs
third_party/rust/itertools-0.6.5/src/adaptors/multipeek.rs
third_party/rust/itertools-0.6.5/src/concat_impl.rs
third_party/rust/itertools-0.6.5/src/cons_tuples_impl.rs
third_party/rust/itertools-0.6.5/src/diff.rs
third_party/rust/itertools-0.6.5/src/format.rs
third_party/rust/itertools-0.6.5/src/free.rs
third_party/rust/itertools-0.6.5/src/groupbylazy.rs
third_party/rust/itertools-0.6.5/src/impl_macros.rs
third_party/rust/itertools-0.6.5/src/intersperse.rs
third_party/rust/itertools-0.6.5/src/kmerge_impl.rs
third_party/rust/itertools-0.6.5/src/lib.rs
third_party/rust/itertools-0.6.5/src/minmax.rs
third_party/rust/itertools-0.6.5/src/pad_tail.rs
third_party/rust/itertools-0.6.5/src/peeking_take_while.rs
third_party/rust/itertools-0.6.5/src/process_results_impl.rs
third_party/rust/itertools-0.6.5/src/rciter_impl.rs
third_party/rust/itertools-0.6.5/src/repeatn.rs
third_party/rust/itertools-0.6.5/src/size_hint.rs
third_party/rust/itertools-0.6.5/src/sources.rs
third_party/rust/itertools-0.6.5/src/tee.rs
third_party/rust/itertools-0.6.5/src/tuple_impl.rs
third_party/rust/itertools-0.6.5/src/with_position.rs
third_party/rust/itertools-0.6.5/src/zip_eq_impl.rs
third_party/rust/itertools-0.6.5/src/zip_longest.rs
third_party/rust/itertools-0.6.5/src/ziptuple.rs
third_party/rust/itertools-0.6.5/tests/peeking_take_while.rs
third_party/rust/itertools-0.6.5/tests/quick.rs
third_party/rust/itertools-0.6.5/tests/tests.rs
third_party/rust/itertools-0.6.5/tests/tuples.rs
third_party/rust/itertools-0.6.5/tests/zip.rs
toolkit/content/widgets/listbox.xml
toolkit/moz.configure
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -176,30 +176,30 @@ dependencies = [
  "proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "which 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "binjs_meta"
-version = "0.3.6"
+version = "0.3.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "Inflector 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "itertools 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "webidl 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "binsource"
 version = "0.1.0"
 dependencies = [
- "binjs_meta 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "binjs_meta 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "webidl 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "yaml-rust 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -944,24 +944,16 @@ version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "itertools"
-version = "0.6.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "itertools"
 version = "0.7.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "itoa"
@@ -2546,17 +2538,17 @@ dependencies = [
 "checksum ascii-canvas 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b385d69402821a1c254533a011a312531cbcc0e3e24f19bbb4747a5a2daf37e2"
 "checksum atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb2dcb6e6d35f20276943cc04bb98e538b348d525a04ac79c10021561d202f21"
 "checksum atty 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d0fd4c0631f06448cc45a6bbb3b710ebb7ff8ccb96a0800c994afe23a70d5df2"
 "checksum atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159"
 "checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9"
 "checksum binary-space-partition 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88ceb0d16c4fd0e42876e298d7d3ce3780dd9ebdcbe4199816a32c77e08597ff"
 "checksum bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bda13183df33055cbb84b847becce220d392df502ebe7a4a78d7021771ed94d0"
 "checksum bindgen 0.37.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1b25ab82877ea8fe6ce1ce1f8ac54361f0218bad900af9eb11803994bf67c221"
-"checksum binjs_meta 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9fcfc86eecb125147e907529a5f1ac7978f6f26d20a52b82a7e053da5faefbc3"
+"checksum binjs_meta 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "fd7ca5635f1c6f94aaef7de76cb834c5920578355ce41dbcaf731b7ebe348518"
 "checksum bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9bf6104718e80d7b26a68fdbacff3481cfc05df670821affc7e9cbc1884400c"
 "checksum bit-vec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "02b4ff8b16e6076c3e14220b39fbc1fabb6737522281a388998046859400895f"
 "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
 "checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf"
 "checksum bitreader 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "80b13e2ab064ff3aa0bdbf1eff533f9822dc37899821f5f98c67f263eab51707"
 "checksum boxfnonce 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8380105befe91099e6f69206164072c05bc92427ff6aa8a5171388317346dd75"
 "checksum build_const 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e90dc84f5e62d2ebe7676b83c22d33b6db8bd27340fb6ffbff0a364efa0cb9c9"
 "checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23"
@@ -2622,17 +2614,16 @@ dependencies = [
 "checksum gleam 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0d41e7ac812597988fdae31c9baec3c6d35cadb8ad9ab88a9bf9c0f119ed66c2"
 "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
 "checksum httparse 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "af2f2dd97457e8fb1ae7c5a420db346af389926e36f43768b96f101546b04a07"
 "checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e"
 "checksum hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)" = "368cb56b2740ebf4230520e2b90ebb0461e69034d85d1945febd9b3971426db2"
 "checksum ident_case 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c9826188e666f2ed92071d2dadef6edc430b11b158b5b2b3f4babbcc891eaaa"
 "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d"
 "checksum iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29d062ee61fccdf25be172e70f34c9f6efc597e1fb8f6526e8437b2046ab26be"
-"checksum itertools 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d3f2be4da1690a039e9ae5fd575f706a63ad5a2120f161b1d653c9da3930dd21"
 "checksum itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b07332223953b5051bceb67e8c4700aa65291535568e1f12408c43c4a42c0394"
 "checksum itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c069bbec61e1ca5a596166e55dfe4773ff745c3d16b700013bcaff9a6df2c682"
 "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
 "checksum khronos_api 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "037ab472c33f67b5fbd3e9163a2645319e5356fcd355efa6d4eb7fff4bbcb554"
 "checksum lalrpop 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88035943c3cfbb897a499a556212b2b053574f32b4238b71b61625bc470f80aa"
 "checksum lalrpop-intern 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cc4fd87be4a815fd373e02773983940f0d75fb26fde8c098e9e45f7af03154c0"
 "checksum lalrpop-snap 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5f244285324e4e33d486910b66fd3b7cb37e2072c5bf63319f506fe99ed72650"
 "checksum lalrpop-util 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "de408fd50dea8ad7a77107144983a25c7fdabf5f8faf707a6e020d68874ed06c"
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -65,20 +65,17 @@ pref("extensions.geckoProfiler.getSymbol
 pref("extensions.geckoProfiler.getSymbolRules", "localBreakpad,dump_syms.exe");
 #endif
 
 
 // Add-on content security policies.
 pref("extensions.webextensions.base-content-security-policy", "script-src 'self' https://* moz-extension: blob: filesystem: 'unsafe-eval' 'unsafe-inline'; object-src 'self' https://* moz-extension: blob: filesystem:;");
 pref("extensions.webextensions.default-content-security-policy", "script-src 'self'; object-src 'self';");
 
-#if defined(XP_WIN) || defined(XP_MACOSX)
 pref("extensions.webextensions.remote", true);
-#endif
-
 pref("extensions.webextensions.background-delayed-startup", true);
 
 // Extensions that should not be flagged as legacy in about:addons
 pref("extensions.legacy.exceptions", "testpilot@cliqz.com,@testpilot-containers,jid1-NeEaf3sAHdKHPA@jetpack,@activity-streams,pulse@mozilla.com,@testpilot-addon,@min-vid,tabcentertest1@mozilla.com,snoozetabs@mozilla.com,speaktome@mozilla.com,hoverpad@mozilla.com");
 
 // Require signed add-ons by default
 pref("extensions.langpacks.signatures.required", true);
 pref("xpinstall.signatures.required", true);
--- a/browser/base/content/browser-siteIdentity.js
+++ b/browser/base/content/browser-siteIdentity.js
@@ -1018,17 +1018,17 @@ var gIdentityHandler = {
     let isPolicyPermission = aPermission.scope == SitePermissions.SCOPE_POLICY;
 
     if (aPermission.id == "popup" && !isPolicyPermission) {
       let menulist = document.createElement("menulist");
       let menupopup = document.createElement("menupopup");
       let block = document.createElement("vbox");
       block.setAttribute("id", "identity-popup-popup-container");
       menulist.setAttribute("sizetopopup", "none");
-      menulist.setAttribute("class", "identity-popup-popup-menulist subviewkeynav");
+      menulist.setAttribute("class", "identity-popup-popup-menulist");
       menulist.setAttribute("id", "identity-popup-popup-menulist");
 
       for (let state of SitePermissions.getAvailableStates(aPermission.id)) {
         let menuitem = document.createElement("menuitem");
         // We need to correctly display the default/unknown state, which has its
         // own integer value (0) but represents one of the other states.
         if (state == SitePermissions.getDefault(aPermission.id)) {
           menuitem.setAttribute("value", "0");
@@ -1085,17 +1085,17 @@ var gIdentityHandler = {
     /* We return the permission item here without a remove button if the permission is a
        SCOPE_POLICY permission. Policy permissions cannot be removed/changed for the duration
        of the browser session. */
     if (isPolicyPermission) {
       return container;
     }
 
     let button = document.createElement("button");
-    button.setAttribute("class", "identity-popup-permission-remove-button subviewkeynav");
+    button.setAttribute("class", "identity-popup-permission-remove-button");
     let tooltiptext = gNavigatorBundle.getString("permissions.remove.tooltip");
     button.setAttribute("tooltiptext", tooltiptext);
     button.addEventListener("command", () => {
       let browser = gBrowser.selectedBrowser;
       this._permissionList.removeChild(container);
       if (aPermission.sharingState &&
           ["camera", "microphone", "screen"].includes(aPermission.id)) {
         let windowId = this._sharingState.windowId;
@@ -1141,17 +1141,17 @@ var gIdentityHandler = {
     indicator.setAttribute("align", "center");
     indicator.setAttribute("id", "blocked-popup-indicator-item");
 
     let icon = document.createElement("image");
     icon.setAttribute("class", "popup-subitem identity-popup-permission-icon");
 
     let text = document.createElement("label");
     text.setAttribute("flex", "1");
-    text.setAttribute("class", "identity-popup-permission-label text-link subviewkeynav");
+    text.setAttribute("class", "identity-popup-permission-label text-link");
 
     let popupCount = gBrowser.selectedBrowser.blockedPopups.length;
     let messageBase = gNavigatorBundle.getString("popupShowBlockedPopupsIndicatorText");
     let message = PluralForm.get(popupCount, messageBase)
                                  .replace("#1", popupCount);
     text.textContent = message;
 
     text.addEventListener("click", () => {
--- a/browser/components/controlcenter/content/panel.inc.xul
+++ b/browser/components/controlcenter/content/panel.inc.xul
@@ -42,17 +42,17 @@
                          when-mixedcontent="passive-loaded">&identity.passiveLoaded;</description>
             <description when-mixedcontent="active-loaded">&identity.activeLoaded;</description>
             <description class="identity-popup-warning-yellow"
                          when-ciphers="weak">&identity.weakEncryption;</description>
             <description when-loginforms="insecure">&identity.insecureLoginForms2;</description>
           </vbox>
         </vbox>
         <button id="identity-popup-security-expander"
-                class="identity-popup-expander subviewkeynav"
+                class="identity-popup-expander"
                 when-connection="not-secure secure secure-ev secure-cert-user-overridden"
                 oncommand="gIdentityHandler.showSecuritySubView();"/>
       </hbox>
 
       <!-- Tracking Protection Section -->
       <hbox id="tracking-protection-container"
             class="identity-popup-section"
             when-connection="not-secure secure secure-ev secure-cert-user-overridden extension">
@@ -79,32 +79,32 @@
           <description id="tracking-loaded-exception"
                        crop="end">&trackingProtection.detectedException;</description>
           <description id="tracking-not-detected-exception"
                        crop="end">&trackingProtection.notDetectedException;</description>
           <description id="tracking-reload-required"
                        crop="end">&trackingProtection.reloadRequired2;</description>
 
           <button id="tracking-action-reload"
-                  class="tracking-protection-button subviewkeynav"
+                  class="tracking-protection-button"
                   label="&trackingProtection.reload2.label;"
                   accesskey="&trackingProtection.reload2.accesskey;"
                   oncommand="TrackingProtection.hideIdentityPopupAndReload();" />
           <button id="tracking-action-unblock"
-                  class="tracking-protection-button subviewkeynav"
+                  class="tracking-protection-button"
                   label="&trackingProtection.unblock3.label;"
                   accesskey="&trackingProtection.unblock3.accesskey;"
                   oncommand="TrackingProtection.disableForCurrentPage();" />
           <button id="tracking-action-unblock-private"
-                  class="tracking-protection-button subviewkeynav"
+                  class="tracking-protection-button"
                   label="&trackingProtection.unblockPrivate3.label;"
                   accesskey="&trackingProtection.unblockPrivate3.accesskey;"
                   oncommand="TrackingProtection.disableForCurrentPage();" />
           <button id="tracking-action-block"
-                  class="tracking-protection-button subviewkeynav"
+                  class="tracking-protection-button"
                   label="&trackingProtection.block4.label;"
                   accesskey="&trackingProtection.block4.accesskey;"
                   oncommand="TrackingProtection.enableForCurrentPage();" />
         </vbox>
       </hbox>
 
       <!-- Permissions Section -->
       <hbox class="identity-popup-section"
@@ -126,18 +126,17 @@
           <description id="identity-popup-permission-empty-hint">&identity.permissionsEmpty;</description>
         </vbox>
       </hbox>
 
       <!-- Clear Site Data Button -->
       <vbox hidden="true"
             id="identity-popup-clear-sitedata-footer"
             class="identity-popup-footer">
-        <button class="subviewkeynav"
-                id="identity-popup-clear-sitedata-button"
+        <button id="identity-popup-clear-sitedata-button"
                 label="&identity.clearSiteData;"
                 oncommand="gIdentityHandler.clearSiteData(event);"/>
       </vbox>
     </panelview>
 
     <!-- Security SubView -->
     <panelview id="identity-popup-securityView"
                title="&identity.securityView.label;"
@@ -162,17 +161,16 @@
                      class="header"/>
         <description id="identity-popup-content-supplemental"
                      when-connection="secure-ev"/>
         <description id="identity-popup-content-verifier"
                      when-connection="secure secure-ev secure-cert-user-overridden"/>
 
         <!-- Remove Certificate Exception -->
         <button when-connection="secure-cert-user-overridden"
-                class="subviewkeynav"
                 label="&identity.removeCertException.label;"
                 accesskey="&identity.removeCertException.accesskey;"
                 oncommand="gIdentityHandler.removeCertException()"/>
 
         <!-- Connection is Not Secure -->
         <description when-connection="not-secure"
                      and-when-loginforms="secure">&identity.description.insecure;</description>
 
@@ -204,28 +202,28 @@
         <description when-mixedcontent="active-loaded"
                      and-when-loginforms="secure">&identity.description.activeLoaded2; <label observes="identity-popup-mcb-learn-more"/></description>
         <!-- Show only the first message when there are insecure login forms,
              and make sure the Learn More link is included. -->
         <description when-mixedcontent="active-loaded"
                      and-when-loginforms="insecure">&identity.description.activeLoaded; <label observes="identity-popup-mcb-learn-more"/></description>
 
         <!-- Buttons to enable/disable mixed content blocking. -->
-        <button when-mixedcontent="active-blocked" class="subviewkeynav"
+        <button when-mixedcontent="active-blocked"
                 label="&identity.disableMixedContentBlocking.label;"
                 accesskey="&identity.disableMixedContentBlocking.accesskey;"
                 oncommand="gIdentityHandler.disableMixedContentProtection()"/>
-        <button when-mixedcontent="active-loaded" class="subviewkeynav"
+        <button when-mixedcontent="active-loaded"
                 label="&identity.enableMixedContentBlocking.label;"
                 accesskey="&identity.enableMixedContentBlocking.accesskey;"
                 oncommand="gIdentityHandler.enableMixedContentProtection()"/>
       </vbox>
 
       <vbox id="identity-popup-more-info-footer" class="identity-popup-footer">
         <!-- More Security Information -->
-        <button id="identity-popup-more-info"  class="subviewkeynav"
+        <button id="identity-popup-more-info"
                 label="&identity.moreInfoLinkText2;"
                 oncommand="gIdentityHandler.handleMoreInfoClick(event);"/>
       </vbox>
 
     </panelview>
   </panelmultiview>
 </panel>
--- a/browser/components/customizableui/PanelMultiView.jsm
+++ b/browser/components/customizableui/PanelMultiView.jsm
@@ -1352,38 +1352,49 @@ var PanelView = class extends Associated
     // Now we can make all the necessary DOM changes at once.
     for (let { element, bounds } of items) {
       gMultiLineElementsMap.set(element, { bounds, textContent: element.textContent });
       element.style.height = bounds.height + "px";
     }
   }
 
   /**
-   * Retrieves the button elements that can be used for navigation using the
-   * keyboard, that is all enabled buttons including the back button if visible.
+   * Array of enabled elements that can be selected with the keyboard. This
+   * means all buttons, menulists, and text links including the back button.
    *
-   * @return {Array}
+   * This list is cached until the view is closed, so elements that become
+   * enabled later may not be navigable.
    */
-  _getNavigableElements() {
-    let buttons = Array.from(this.node.querySelectorAll(
-      ".subviewbutton:not([disabled]), .subviewkeynav:not([disabled])"));
+  get _navigableElements() {
+    if (this.__navigableElements) {
+      return this.__navigableElements;
+    }
+
+    let navigableElements = Array.from(this.node.querySelectorAll(
+      ":-moz-any(button,toolbarbutton,menulist,.text-link):not([disabled])"));
     let dwu = this._dwu;
-    return buttons.filter(button => {
-      let bounds = dwu.getBoundsWithoutFlushing(button);
+    return this.__navigableElements = navigableElements.filter(element => {
+      // Set the "tabindex" attribute to make sure the element is focusable.
+      if (!element.hasAttribute("tabindex")) {
+        element.setAttribute("tabindex", "0");
+      }
+      if (element.hasAttribute("disabled")) {
+        return false;
+      }
+      let bounds = dwu.getBoundsWithoutFlushing(element);
       return bounds.width > 0 && bounds.height > 0;
     });
   }
 
   /**
    * Element that is currently selected with the keyboard, or null if no element
    * is selected. Since the reference is held weakly, it can become null or
    * undefined at any time.
    *
-   * The element is usually, but not necessarily, in the "buttons" property
-   * which in turn is initialized from the _getNavigableElements list.
+   * The element is usually, but not necessarily, among the _navigableElements.
    */
   get selectedElement() {
     return this._selectedElement && this._selectedElement.get();
   }
   set selectedElement(value) {
     if (!value) {
       delete this._selectedElement;
     } else {
@@ -1391,29 +1402,29 @@ var PanelView = class extends Associated
     }
   }
 
   /**
    * Focuses and moves keyboard selection to the first navigable element.
    * This is a no-op if there are no navigable elements.
    */
   focusFirstNavigableElement() {
-    this.selectedElement = this._getNavigableElements()[0];
+    this.selectedElement = this._navigableElements[0];
     this.focusSelectedElement();
   }
 
   /**
-   * Based on going up or down, select the previous or next focusable button.
+   * Based on going up or down, select the previous or next focusable element.
    *
    * @param {Boolean} isDown   whether we're going down (true) or up (false).
    *
-   * @return {DOMNode} the button we selected.
+   * @return {DOMNode} the element we selected.
    */
   moveSelection(isDown) {
-    let buttons = this.buttons;
+    let buttons = this._navigableElements;
     let lastSelected = this.selectedElement;
     let newButton = null;
     let maxIdx = buttons.length - 1;
     if (lastSelected) {
       let buttonIndex = buttons.indexOf(lastSelected);
       if (buttonIndex != -1) {
         // Buttons may get selected whilst the panel is shown, so add an extra
         // check here.
@@ -1473,29 +1484,20 @@ var PanelView = class extends Associated
    * @param {String} dir
    *        Direction for arrow navigation, either "ltr" or "rtl".
    */
   keyNavigation(event, dir) {
     if (!this.active) {
       return;
     }
 
-    let buttons = this.buttons;
-    if (!buttons || !buttons.length) {
-      buttons = this.buttons = this._getNavigableElements();
-      // Set the 'tabindex' attribute on the buttons to make sure they're focussable.
-      for (let button of buttons) {
-        if (!button.classList.contains("subviewbutton-back") &&
-            !button.hasAttribute("tabindex")) {
-          button.setAttribute("tabindex", 0);
-        }
-      }
+    let buttons = this._navigableElements;
+    if (!buttons.length) {
+      return;
     }
-    if (!buttons.length)
-      return;
 
     let stop = () => {
       event.stopPropagation();
       event.preventDefault();
     };
 
     let keyCode = event.code;
     switch (keyCode) {
@@ -1554,16 +1556,16 @@ var PanelView = class extends Associated
       selected.focus();
     }
   }
 
   /**
    * Clear all traces of keyboard navigation happening right now.
    */
   clearNavigation() {
-    delete this.buttons;
+    delete this.__navigableElements;
     let selected = this.selectedElement;
     if (selected) {
       selected.blur();
       this.selectedElement = null;
     }
   }
 };
--- a/browser/components/customizableui/content/panelUI.inc.xul
+++ b/browser/components/customizableui/content/panelUI.inc.xul
@@ -212,17 +212,16 @@
         <toolbaritem id="appMenu-tp-container" hidden="true" closemenu="none">
           <toolbarbutton id="appMenu-tp-label"
                          tooltiptext="&trackingProtection.tooltip;"
                          class="subviewbutton subviewbutton-iconic"
                          oncommand="TrackingProtection.openPreferences('appMenu-trackingprotection'); PanelUI.hide();"
                          label="&trackingProtection.title;"/>
           <toolbarseparator orient="vertical"/>
           <toolbarbutton id="appMenu-tp-toggle"
-                         class="subviewkeynav"
                          enabled="false"
                          oncommand="TrackingProtection.onGlobalToggleCommand();" />
         </toolbaritem>
         <toolbarseparator id="appMenu-tp-separator" hidden="true" />
         <toolbarbutton id="appMenu-new-window-button"
                        class="subviewbutton subviewbutton-iconic"
                        label="&newNavigatorCmd.label;"
                        key="key_newNavigator"
--- a/browser/components/customizableui/test/browser_panel_keyboard_navigation.js
+++ b/browser/components/customizableui/test/browser_panel_keyboard_navigation.js
@@ -2,20 +2,29 @@
 
 /**
  * Test keyboard navigation in the app menu panel.
  */
 
 const {PanelView} = ChromeUtils.import("resource:///modules/PanelMultiView.jsm", {});
 const kHelpButtonId = "appMenu-help-button";
 
+function getEnabledNavigableElementsForView(panelView) {
+  return Array.from(panelView.querySelectorAll(
+    "button,toolbarbutton,menulist,.text-link"
+  )).filter(element => {
+    let bounds = element.getBoundingClientRect();
+    return !element.disabled && (bounds.width > 0 && bounds.height > 0);
+  });
+}
+
 add_task(async function testUpDownKeys() {
   await gCUITestUtils.openMainMenu();
 
-  let buttons = PanelView.forNode(PanelUI.mainView)._getNavigableElements();
+  let buttons = getEnabledNavigableElementsForView(PanelUI.mainView);
 
   for (let button of buttons) {
     if (button.disabled)
       continue;
     EventUtils.synthesizeKey("KEY_ArrowDown");
     Assert.equal(document.commandDispatcher.focusedElement, button,
       "The correct button should be focused after navigating downward");
   }
@@ -34,34 +43,34 @@ add_task(async function testUpDownKeys()
   }
 
   await gCUITestUtils.hideMainMenu();
 });
 
 add_task(async function testEnterKeyBehaviors() {
   await gCUITestUtils.openMainMenu();
 
-  let buttons = PanelView.forNode(PanelUI.mainView)._getNavigableElements();
+  let buttons = getEnabledNavigableElementsForView(PanelUI.mainView);
 
   // Navigate to the 'Help' button, which points to a subview.
   EventUtils.synthesizeKey("KEY_ArrowUp");
   let focusedElement = document.commandDispatcher.focusedElement;
   Assert.equal(focusedElement, buttons[buttons.length - 1],
     "The last button should be focused after navigating upward");
 
   let promise = BrowserTestUtils.waitForEvent(PanelUI.helpView, "ViewShown");
   // Make sure the Help button is in focus.
   while (!focusedElement || !focusedElement.id || focusedElement.id != kHelpButtonId) {
     EventUtils.synthesizeKey("KEY_ArrowUp");
     focusedElement = document.commandDispatcher.focusedElement;
   }
   EventUtils.synthesizeKey("KEY_Enter");
   await promise;
 
-  let helpButtons = PanelView.forNode(PanelUI.helpView)._getNavigableElements();
+  let helpButtons = getEnabledNavigableElementsForView(PanelUI.helpView);
   Assert.ok(helpButtons[0].classList.contains("subviewbutton-back"),
     "First button in help view should be a back button");
 
   // For posterity, check navigating the subview using up/ down arrow keys as well.
   for (let i = helpButtons.length - 1; i >= 0; --i) {
     let button = helpButtons[i];
     if (button.disabled)
       continue;
@@ -127,17 +136,17 @@ add_task(async function testLeftRightKey
                "Help button should be focused again now that we're back in the main view");
 
   await gCUITestUtils.hideMainMenu();
 });
 
 add_task(async function testTabKey() {
   await gCUITestUtils.openMainMenu();
 
-  let buttons = PanelView.forNode(PanelUI.mainView)._getNavigableElements();
+  let buttons = getEnabledNavigableElementsForView(PanelUI.mainView);
 
   for (let button of buttons) {
     if (button.disabled)
       continue;
     EventUtils.synthesizeKey("KEY_Tab");
     Assert.equal(document.commandDispatcher.focusedElement, button,
       "The correct button should be focused after tabbing");
   }
@@ -160,17 +169,17 @@ add_task(async function testTabKey() {
     "Pressing shift + tab should cycle around and select the last button again");
 
   await gCUITestUtils.hideMainMenu();
 });
 
 add_task(async function testInterleavedTabAndArrowKeys() {
   await gCUITestUtils.openMainMenu();
 
-  let buttons = PanelView.forNode(PanelUI.mainView)._getNavigableElements();
+  let buttons = getEnabledNavigableElementsForView(PanelUI.mainView);
   let tab = false;
 
   for (let button of buttons) {
     if (button.disabled)
       continue;
     if (tab) {
       EventUtils.synthesizeKey("KEY_Tab");
     } else {
@@ -183,17 +192,17 @@ add_task(async function testInterleavedT
     "The last button should be focused after a mix of Tab and ArrowDown");
 
   await gCUITestUtils.hideMainMenu();
 });
 
 add_task(async function testSpaceDownAfterTabNavigation() {
   await gCUITestUtils.openMainMenu();
 
-  let buttons = PanelView.forNode(PanelUI.mainView)._getNavigableElements();
+  let buttons = getEnabledNavigableElementsForView(PanelUI.mainView);
   let button;
 
   for (button of buttons) {
     if (button.disabled)
       continue;
     EventUtils.synthesizeKey("KEY_Tab");
     if (button.id == kHelpButtonId) {
       break;
--- a/browser/components/extensions/test/browser/browser_ext_browserAction_popup_preload.js
+++ b/browser/components/extensions/test/browser/browser_ext_browserAction_popup_preload.js
@@ -197,15 +197,17 @@ add_task(async function testBrowserActio
   // Make sure the mouse isn't hovering over the browserAction widget.
   EventUtils.synthesizeMouseAtCenter(win.gURLBar, {type: "mouseover"}, win);
 
   await extension.startup();
 
   let widget = getBrowserActionWidget(extension).forWindow(win);
   EventUtils.synthesizeMouseAtCenter(widget.node, {type: "mousedown", button: 0}, win);
 
-  await extension.awaitMessage("tabTitle");
+  await new Promise(resolve => setTimeout(resolve, 100));
 
   EventUtils.synthesizeMouseAtCenter(widget.node, {type: "mouseup", button: 0}, win);
 
+  await extension.awaitMessage("tabTitle");
+
   await extension.unload();
   await BrowserTestUtils.closeWindow(win);
 });
--- a/browser/themes/osx/browser.css
+++ b/browser/themes/osx/browser.css
@@ -208,24 +208,16 @@
 #panelMenu_unsortedBookmarks {
   list-style-image: url("chrome://browser/skin/places/unfiledBookmarks.svg");
 }
 
 %include ../shared/toolbarbuttons.inc.css
 %include ../shared/toolbarbutton-icons.inc.css
 %include ../shared/menupanel.inc.css
 
-/* Override OSX-specific toolkit findbar button styles */
-.findbar-button {
-  background: none;
-  box-shadow: none;
-  border: none;
-  color: inherit;
-}
-
 /* On Mac, native buttons keep their full opacity when they become disabled
  * and only the glyph or text on top of them becomes less opaque. */
 :root:not([customizing]) #back-button[disabled="true"] {
   opacity: 1 !important;
   /* Disabled toolbar buttons get an opacity of 0.4 which multiplies
    * their fill-opacity of 0.7. calc() doesn't work here - we'd need
    * to multiply two unitless numbers and that's invalid in CSS, so
    * we need to hard code the value for now. */
--- a/browser/themes/shared/toolbarbuttons.inc.css
+++ b/browser/themes/shared/toolbarbuttons.inc.css
@@ -86,22 +86,16 @@ toolbar[brighttext] {
 #navigator-toolbox:not(:hover) > #TabsToolbar > #tabbrowser-tabs > .tabbrowser-arrowscrollbox > .scrollbutton-down:not([highlight]) {
   transition: 1s background-color ease-out;
 }
 
 .tabbrowser-arrowscrollbox > .scrollbutton-down[highlight] {
   background-color: Highlight;
 }
 
-.findbar-button {
-  -moz-appearance: none;
-  padding: 0;
-  color: inherit;
-}
-
 toolbar .toolbarbutton-1 {
   -moz-appearance: none;
   margin: 0;
   padding: 0 var(--toolbarbutton-outer-padding);
   -moz-box-pack: center;
 }
 
 :root:not([uidensity=compact]) #PanelUI-menu-button {
--- a/config/system-headers.mozbuild
+++ b/config/system-headers.mozbuild
@@ -1341,8 +1341,25 @@ if CONFIG['ENABLE_BIGINT']:
     ]
 
 if CONFIG['MOZ_WAYLAND']:
     system_headers += [
         'xkbcommon/xkbcommon.h',
         'wayland-client.h',
         'wayland-egl.h',
     ]
+
+if CONFIG['MOZ_LIB_SECRET']:
+    system_headers += [
+        'libsecret/secret.h',
+        'libsecret/secret-attributes.h',
+        'libsecret/secret-collection.h',
+        'libsecret/secret-enum-types.h',
+        'libsecret/secret-item.h',
+        'libsecret/secret-password.h',
+        'libsecret/secret-paths.h',
+        'libsecret/secret-prompt.h',
+        'libsecret/secret-schema.h',
+        'libsecret/secret-schemas.h',
+        'libsecret/secret-types.h',
+        'libsecret/secret-value.h',
+        'libsecret/secret-service.h',
+    ]
--- a/devtools/client/debugger/new/README.mozilla
+++ b/devtools/client/debugger/new/README.mozilla
@@ -1,13 +1,13 @@
 This is the debugger.html project output.
 See https://github.com/devtools-html/debugger.html
 
-Version 74
+Version 75
 
-Comparison: https://github.com/devtools-html/debugger.html/compare/release-73...release-74
+Comparison: https://github.com/devtools-html/debugger.html/compare/release-74...release-75
 
 Packages:
 - babel-plugin-transform-es2015-modules-commonjs @6.26.2
 - babel-preset-react @6.24.1
 - react @16.4.1
 - react-dom @16.4.1
 - webpack @3.11.0
--- a/devtools/client/debugger/new/dist/debugger.css
+++ b/devtools/client/debugger/new/dist/debugger.css
@@ -50,18 +50,16 @@
   }
 }
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
 
 .shortcuts-content {
   padding: 15px;
-  -moz-column-width: 250px;
-  -webkit-column-width: 250px;
   column-width: 250px;
   cursor: default;
 }
 
 .shortcuts-content h2 {
   margin-top: 2px;
   margin-bottom: 2px;
   color: var(--theme-content-color1);
--- a/devtools/client/debugger/new/dist/parser-worker.js
+++ b/devtools/client/debugger/new/dist/parser-worker.js
@@ -23166,18 +23166,19 @@ function buildMetaBindings(sourceId, nod
     return {
       type: "inherit",
       start: fromBabelLocation(start, sourceId),
       end: fromBabelLocation(end, sourceId),
       parent: buildMetaBindings(sourceId, parent, ancestors, parentIndex - 1)
     };
   }
 
-  // Consider "Object(foo)" to be equivalent to "foo"
-  if (t.isCallExpression(parent) && t.isIdentifier(parent.callee, { name: "Object" }) && parent.arguments.length === 1 && parent.arguments[0] === node) {
+  // Consider "Object(foo)", and "__webpack_require__.i(foo)" to be
+  // equivalent to "foo" since they are essentially identity functions.
+  if (t.isCallExpression(parent) && (t.isIdentifier(parent.callee, { name: "Object" }) || t.isMemberExpression(parent.callee, { computed: false }) && t.isIdentifier(parent.callee.object, { name: "__webpack_require__" }) && t.isIdentifier(parent.callee.property, { name: "i" })) && parent.arguments.length === 1 && parent.arguments[0] === node) {
     return {
       type: "inherit",
       start: fromBabelLocation(parent.loc.start, sourceId),
       end: fromBabelLocation(parent.loc.end, sourceId),
       parent: buildMetaBindings(sourceId, parent, ancestors, parentIndex - 1)
     };
   }
 
--- a/devtools/client/debugger/new/src/components/Editor/Breakpoint.js
+++ b/devtools/client/debugger/new/src/components/Editor/Breakpoint.js
@@ -39,21 +39,21 @@ function makeMarker(isDisabled) {
   const bp = breakpointSvg.cloneNode(true);
   bp.className = (0, _classnames2.default)("editor new-breakpoint", {
     "breakpoint-disabled": isDisabled,
     "folding-enabled": _prefs.features.codeFolding
   });
   return bp;
 }
 
-class Breakpoint extends _react.Component {
-  constructor() {
-    super();
+class Breakpoint extends _react.PureComponent {
+  constructor(...args) {
+    var _temp;
 
-    this.addBreakpoint = () => {
+    return _temp = super(...args), this.addBreakpoint = () => {
       const {
         breakpoint,
         editor,
         selectedSource
       } = this.props; // Hidden Breakpoints are never rendered on the client
 
       if (breakpoint.hidden) {
         return;
@@ -70,17 +70,17 @@ class Breakpoint extends _react.Componen
       editor.codeMirror.setGutterMarker(line, "breakpoints", makeMarker(breakpoint.disabled));
       editor.codeMirror.addLineClass(line, "line", "new-breakpoint");
 
       if (breakpoint.condition) {
         editor.codeMirror.addLineClass(line, "line", "has-condition");
       } else {
         editor.codeMirror.removeLineClass(line, "line", "has-condition");
       }
-    };
+    }, _temp;
   }
 
   componentDidMount() {
     this.addBreakpoint();
   }
 
   componentDidUpdate() {
     this.addBreakpoint();
--- a/devtools/client/debugger/new/src/components/Editor/index.js
+++ b/devtools/client/debugger/new/src/components/Editor/index.js
@@ -163,17 +163,17 @@ class Editor extends _react.PureComponen
         selectedSource,
         conditionalPanelLine,
         closeConditionalPanel,
         addOrToggleDisabledBreakpoint,
         toggleBreakpointsAtLine,
         continueToHere
       } = this.props; // ignore right clicks in the gutter
 
-      if (ev.ctrlKey && ev.button === 0 || ev.which === 3 || selectedSource && selectedSource.isBlackBoxed || !selectedSource) {
+      if (ev.ctrlKey && ev.button === 0 || ev.button === 2 || selectedSource && selectedSource.isBlackBoxed || !selectedSource) {
         return;
       }
 
       if (conditionalPanelLine) {
         return closeConditionalPanel();
       }
 
       if (gutter === "CodeMirror-foldgutter") {
@@ -338,16 +338,21 @@ class Editor extends _react.PureComponen
 
   getCurrentLine() {
     const {
       codeMirror
     } = this.state.editor;
     const {
       selectedSource
     } = this.props;
+
+    if (!selectedSource) {
+      return;
+    }
+
     const line = (0, _editor.getCursorLine)(codeMirror);
     return (0, _editor.toSourceLine)(selectedSource.id, line);
   }
 
   onKeyDown(e) {
     const {
       codeMirror
     } = this.state.editor;
@@ -377,67 +382,72 @@ class Editor extends _react.PureComponen
 
 
   openMenu(event) {
     event.stopPropagation();
     event.preventDefault();
     const {
       setContextMenu
     } = this.props;
+    const target = event.target;
 
-    if (event.target.classList.contains("CodeMirror-linenumber")) {
+    if (target.classList.contains("CodeMirror-linenumber")) {
       return setContextMenu("Gutter", event);
     }
 
     return setContextMenu("Editor", event);
   }
 
   onClick(e) {
     const {
       selectedLocation,
       jumpToMappedLocation
     } = this.props;
 
-    if (e.metaKey && e.altKey) {
+    if (selectedLocation && e.metaKey && e.altKey) {
       const sourceLocation = (0, _editor.getSourceLocationFromMouseEvent)(this.state.editor, selectedLocation, e);
       jumpToMappedLocation(sourceLocation);
     }
   }
 
   shouldScrollToLocation(nextProps) {
     const {
       selectedLocation,
       selectedSource
     } = this.props;
     const {
       editor
     } = this.state;
 
-    if (!editor || !nextProps.selectedSource || !nextProps.selectedLocation || !(0, _source.isLoaded)(nextProps.selectedSource)) {
+    if (!editor || !nextProps.selectedSource || !nextProps.selectedLocation || !nextProps.selectedLocation.line || !(0, _source.isLoaded)(nextProps.selectedSource)) {
       return false;
     }
 
     const isFirstLoad = (!selectedSource || !(0, _source.isLoaded)(selectedSource)) && (0, _source.isLoaded)(nextProps.selectedSource);
     const locationChanged = selectedLocation !== nextProps.selectedLocation;
     return isFirstLoad || locationChanged;
   }
 
   scrollToLocation(nextProps) {
     const {
       editor
     } = this.state;
+    const {
+      selectedLocation,
+      selectedSource
+    } = nextProps;
 
-    if (this.shouldScrollToLocation(nextProps)) {
+    if (selectedLocation && this.shouldScrollToLocation(nextProps)) {
       let {
         line,
         column
-      } = (0, _editor.toEditorPosition)(nextProps.selectedLocation);
+      } = (0, _editor.toEditorPosition)(selectedLocation);
 
-      if ((0, _editor.hasDocument)(nextProps.selectedSource.id)) {
-        const doc = (0, _editor.getDocument)(nextProps.selectedSource.id);
+      if (selectedSource && (0, _editor.hasDocument)(selectedSource.id)) {
+        const doc = (0, _editor.getDocument)(selectedSource.id);
         const lineText = doc.getLine(line);
         column = Math.max(column, (0, _indentation.getIndentation)(lineText));
       }
 
       (0, _editor.scrollToColumn)(editor.codeMirror, line, column);
     }
   }
 
--- a/devtools/client/debugger/new/src/components/SecondaryPanes/CommandBar.js
+++ b/devtools/client/debugger/new/src/components/SecondaryPanes/CommandBar.js
@@ -144,21 +144,21 @@ class CommandBar extends _react.Componen
   renderPauseButton() {
     const {
       isPaused,
       breakOnNext,
       isWaitingOnBreak,
       canRewind
     } = this.props;
 
-    if (canRewind) {
-      return;
-    }
+    if (isPaused) {
+      if (canRewind) {
+        return null;
+      }
 
-    if (isPaused) {
       return (0, _CommandBarButton.debugBtn)(() => this.resume(), "resume", "active", L10N.getFormatStr("resumeButtonTooltip", formatKey("resume")));
     }
 
     if (_prefs.features.removeCommandBarOptions && !this.props.canRewind) {
       return;
     }
 
     if (isWaitingOnBreak) {
@@ -174,17 +174,17 @@ class CommandBar extends _react.Componen
       canRewind
     } = this.props;
 
     if (!canRewind || !isPaused) {
       return null;
     }
 
     const isDisabled = !isPaused;
-    return [(0, _CommandBarButton.debugBtn)(this.props.rewind, "rewind", "active", "Rewind Execution"), (0, _CommandBarButton.debugBtn)(() => this.props.resume, "resume", "active", L10N.getFormatStr("resumeButtonTooltip", formatKey("resume"))), _react2.default.createElement("div", {
+    return [(0, _CommandBarButton.debugBtn)(this.props.rewind, "rewind", "active", "Rewind Execution"), (0, _CommandBarButton.debugBtn)(this.props.resume, "resume", "active", L10N.getFormatStr("resumeButtonTooltip", formatKey("resume"))), _react2.default.createElement("div", {
       key: "divider-1",
       className: "divider"
     }), (0, _CommandBarButton.debugBtn)(this.props.reverseStepOver, "reverseStepOver", "active", "Reverse step over"), (0, _CommandBarButton.debugBtn)(this.props.stepOver, "stepOver", "active", L10N.getFormatStr("stepOverTooltip", formatKey("stepOver")), isDisabled), _react2.default.createElement("div", {
       key: "divider-2",
       className: "divider"
     }), (0, _CommandBarButton.debugBtn)(this.props.stepOut, "stepOut", "active", L10N.getFormatStr("stepOutTooltip", formatKey("stepOut")), isDisabled), (0, _CommandBarButton.debugBtn)(this.props.stepIn, "stepIn", "active", L10N.getFormatStr("stepInTooltip", formatKey("stepIn")), isDisabled)];
   }
 
--- a/devtools/client/debugger/new/src/components/SecondaryPanes/index.js
+++ b/devtools/client/debugger/new/src/components/SecondaryPanes/index.js
@@ -63,20 +63,16 @@ var _CommandBar2 = _interopRequireDefaul
 var _UtilsBar = require("./UtilsBar");
 
 var _UtilsBar2 = _interopRequireDefault(_UtilsBar);
 
 var _FrameworkComponent = require("./FrameworkComponent");
 
 var _FrameworkComponent2 = _interopRequireDefault(_FrameworkComponent);
 
-var _ReactComponentStack = require("./ReactComponentStack");
-
-var _ReactComponentStack2 = _interopRequireDefault(_ReactComponentStack);
-
 var _Scopes = require("./Scopes");
 
 var _Scopes2 = _interopRequireDefault(_Scopes);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -176,27 +172,16 @@ class SecondaryPanes extends _react.Comp
       component: _react2.default.createElement(_Scopes2.default, null),
       opened: _prefs.prefs.scopesVisible,
       onToggle: opened => {
         _prefs.prefs.scopesVisible = opened;
       }
     };
   }
 
-  getComponentStackItem() {
-    return {
-      header: L10N.getStr("components.header"),
-      component: _react2.default.createElement(_ReactComponentStack2.default, null),
-      opened: _prefs.prefs.componentStackVisible,
-      onToggle: opened => {
-        _prefs.prefs.componentStackVisible = opened;
-      }
-    };
-  }
-
   getComponentItem() {
     const {
       extra: {
         react
       }
     } = this.props;
     return {
       header: react.displayName,
@@ -287,21 +272,17 @@ class SecondaryPanes extends _react.Comp
     }
 
     items.push(this.getBreakpointsItem());
 
     if (this.props.hasFrames) {
       items.push(this.getCallStackItem());
 
       if (this.props.horizontal) {
-        if (extra && extra.react) {
-          if (_prefs.features.componentStack && extra.react.componentStack.length > 1) {
-            items.push(this.getComponentStackItem());
-          }
-
+        if (_prefs.features.componentPane && extra && extra.react) {
           items.push(this.getComponentItem());
         }
 
         items.push(this.getScopeItem());
       }
     }
 
     if (_prefs.features.eventListeners) {
@@ -333,17 +314,17 @@ class SecondaryPanes extends _react.Comp
     }
 
     if (_prefs.features.workers && workers.size > 0) {
       items.push(this.getWorkersItem());
     }
 
     items.push(this.getWatchItem());
 
-    if (extra && extra.react) {
+    if (_prefs.features.componentPane && extra && extra.react) {
       items.push(this.getComponentItem());
     }
 
     if (this.props.hasFrames) {
       items = [...items, this.getScopeItem()];
     }
 
     return items;
--- a/devtools/client/debugger/new/src/components/SecondaryPanes/moz.build
+++ b/devtools/client/debugger/new/src/components/SecondaryPanes/moz.build
@@ -9,13 +9,12 @@ DIRS += [
 ]
 
 DevToolsModules(
     'CommandBar.js',
     'EventListeners.js',
     'Expressions.js',
     'FrameworkComponent.js',
     'index.js',
-    'ReactComponentStack.js',
     'Scopes.js',
     'UtilsBar.js',
     'Workers.js',
 )
--- a/devtools/client/debugger/new/src/components/shared/Accordion.js
+++ b/devtools/client/debugger/new/src/components/shared/Accordion.js
@@ -27,16 +27,17 @@ class Accordion extends _react.Component
       } = item;
       return _react2.default.createElement("li", {
         role: "listitem",
         className: item.className,
         key: i
       }, _react2.default.createElement("h2", {
         className: "_header",
         tabIndex: "0",
+        onKeyDown: e => this.onHandleHeaderKeyDown(e, i),
         onClick: () => this.handleHeaderClick(i)
       }, _react2.default.createElement(_Svg2.default, {
         name: "arrow",
         className: opened ? "expanded" : ""
       }), item.header, item.buttons ? _react2.default.createElement("div", {
         className: "header-buttons",
         tabIndex: "-1"
       }, item.buttons) : null), opened && _react2.default.createElement("div", {
@@ -59,16 +60,22 @@ class Accordion extends _react.Component
       item.onToggle(opened);
     } // We force an update because otherwise the accordion
     // would not re-render
 
 
     this.forceUpdate();
   }
 
+  onHandleHeaderKeyDown(e, i) {
+    if (e && (e.key === " " || e.key === "Enter")) {
+      this.handleHeaderClick(i);
+    }
+  }
+
   render() {
     return _react2.default.createElement("ul", {
       role: "list",
       className: "accordion"
     }, this.props.items.map(this.renderContainer));
   }
 
 }
--- a/devtools/client/debugger/new/src/utils/editor/source-documents.js
+++ b/devtools/client/debugger/new/src/utils/editor/source-documents.js
@@ -155,17 +155,17 @@ function showSourceText(editor, source, 
 
   if (hasDocument(source.id)) {
     const doc = getDocument(source.id);
 
     if (editor.codeMirror.doc === doc) {
       const mode = (0, _source.getMode)(source, symbols);
       const currentMode = editor.codeMirror.getOption("mode");
 
-      if (currentMode.name !== mode.name) {
+      if (currentMode.name != mode.name) {
         editor.setMode(mode);
       }
 
       return;
     }
 
     editor.replaceDocument(doc);
     updateLineNumberFormat(editor, source.id);
--- a/devtools/client/debugger/new/src/utils/indentation.js
+++ b/devtools/client/debugger/new/src/utils/indentation.js
@@ -9,17 +9,23 @@ exports.correctIndentation = correctInde
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
 function getIndentation(line) {
   if (!line) {
     return 0;
   }
 
-  return line.match(/^\s*/)[0].length;
+  const lineMatch = line.match(/^\s*/);
+
+  if (!lineMatch) {
+    return 0;
+  }
+
+  return lineMatch[0].length;
 }
 
 function getMaxIndentation(lines) {
   const firstLine = lines[0];
   const secondLine = lines[1];
   const lastLine = lines[lines.length - 1];
   const indentations = [getIndentation(firstLine), getIndentation(secondLine), getIndentation(lastLine)];
   return Math.max(...indentations);
--- a/devtools/client/debugger/new/src/utils/pause/mapScopes/findGeneratedBindingFromPosition.js
+++ b/devtools/client/debugger/new/src/utils/pause/mapScopes/findGeneratedBindingFromPosition.js
@@ -191,31 +191,43 @@ async function mapImportReferenceToDescr
   // forms, both of which map the "bar" identifier in different ways. See
   // the "^^" markers below for the ranges.
   //
   //   (0, foo.bar)()    // Babel
   //       ^^^^^^^       // mapping
   //       ^^^           // binding
   // vs
   //
-  //   Object(foo.bar)() // Webpack
+  //   __webpack_require__.i(foo.bar)() // Webpack 2
+  //   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   // mapping
+  //                         ^^^        // binding
+  // vs
+  //
+  //   Object(foo.bar)() // Webpack >= 3
   //   ^^^^^^^^^^^^^^^   // mapping
   //          ^^^        // binding
   //
   // Unfortunately, Webpack also has a tendancy to over-map past the call
   // expression to the start of the next line, at least when there isn't
   // anything else on that line that is mapped, e.g.
   //
   //   Object(foo.bar)()
   //   ^^^^^^^^^^^^^^^^^
   //   ^                 // wrapped to column 0 of next line
 
 
   if (!(0, _mappingContains.mappingContains)(range, binding.loc)) {
     return null;
+  } // Webpack 2's import declarations wrap calls with an identity fn, so we
+  // need to make sure to skip that binding because it is mapped to the
+  // location of the original binding usage.
+
+
+  if (binding.name === "__webpack_require__" && binding.loc.meta && binding.loc.meta.type === "member" && binding.loc.meta.property === "i") {
+    return null;
   }
 
   let expression = binding.name;
   let desc = await binding.desc();
 
   if (binding.loc.type === "ref") {
     const {
       meta
--- a/devtools/client/debugger/new/src/utils/pause/pausePoints.js
+++ b/devtools/client/debugger/new/src/utils/pause/pausePoints.js
@@ -43,15 +43,13 @@ function formatPausePoints(text, pausePo
     const {
       line,
       column
     } = node.location;
     const {
       break: breakPoint,
       step
     } = node.types;
-    const num = nodes.length - index;
     const types = `${breakPoint ? "b" : ""}${step ? "s" : ""}`;
-    const spacer = breakPoint || step ? " " : "";
-    lines[line - 1] = insertStrtAt(lines[line - 1], column, `/*${types}${spacer}${num}*/`);
+    lines[line - 1] = insertStrtAt(lines[line - 1], column, `/*${types}*/`);
   });
   return lines.join("\n");
 }
\ No newline at end of file
--- a/devtools/client/debugger/new/src/utils/prefs.js
+++ b/devtools/client/debugger/new/src/utils/prefs.js
@@ -24,17 +24,16 @@ if (isDevelopment()) {
   pref("devtools.debugger.auto-pretty-print", false);
   pref("devtools.source-map.client-service.enabled", true);
   pref("devtools.debugger.pause-on-exceptions", false);
   pref("devtools.debugger.pause-on-caught-exceptions", false);
   pref("devtools.debugger.ignore-caught-exceptions", true);
   pref("devtools.debugger.call-stack-visible", true);
   pref("devtools.debugger.scopes-visible", true);
   pref("devtools.debugger.component-visible", true);
-  pref("devtools.debugger.component-stack-visible", false);
   pref("devtools.debugger.workers-visible", true);
   pref("devtools.debugger.expressions-visible", true);
   pref("devtools.debugger.breakpoints-visible", true);
   pref("devtools.debugger.start-panel-collapsed", false);
   pref("devtools.debugger.end-panel-collapsed", false);
   pref("devtools.debugger.tabs", "[]");
   pref("devtools.debugger.tabsBlackBoxed", "[]");
   pref("devtools.debugger.ui.framework-grouping-on", true);
@@ -57,34 +56,32 @@ if (isDevelopment()) {
   pref("devtools.debugger.features.remove-command-bar-options", true);
   pref("devtools.debugger.features.code-coverage", false);
   pref("devtools.debugger.features.event-listeners", false);
   pref("devtools.debugger.features.code-folding", false);
   pref("devtools.debugger.features.outline", true);
   pref("devtools.debugger.features.column-breakpoints", true);
   pref("devtools.debugger.features.replay", true);
   pref("devtools.debugger.features.pause-points", true);
-  pref("devtools.debugger.features.skip-pausing", false);
+  pref("devtools.debugger.features.skip-pausing", true);
   pref("devtools.debugger.features.component-pane", false);
-  pref("devtools.debugger.features.skip-pausing", true);
   pref("devtools.debugger.features.autocomplete-expressions", false);
   pref("devtools.debugger.features.map-expression-bindings", true);
 }
 
 const prefs = exports.prefs = new PrefsHelper("devtools", {
   alphabetizeOutline: ["Bool", "debugger.alphabetize-outline"],
   autoPrettyPrint: ["Bool", "debugger.auto-pretty-print"],
   clientSourceMapsEnabled: ["Bool", "source-map.client-service.enabled"],
   pauseOnExceptions: ["Bool", "debugger.pause-on-exceptions"],
   pauseOnCaughtExceptions: ["Bool", "debugger.pause-on-caught-exceptions"],
   ignoreCaughtExceptions: ["Bool", "debugger.ignore-caught-exceptions"],
   callStackVisible: ["Bool", "debugger.call-stack-visible"],
   scopesVisible: ["Bool", "debugger.scopes-visible"],
   componentVisible: ["Bool", "debugger.component-visible"],
-  componentStackVisible: ["Bool", "debugger.component-stack-visible"],
   workersVisible: ["Bool", "debugger.workers-visible"],
   breakpointsVisible: ["Bool", "debugger.breakpoints-visible"],
   expressionsVisible: ["Bool", "debugger.expressions-visible"],
   startPanelCollapsed: ["Bool", "debugger.start-panel-collapsed"],
   endPanelCollapsed: ["Bool", "debugger.end-panel-collapsed"],
   frameworkGroupingOn: ["Bool", "debugger.ui.framework-grouping-on"],
   tabs: ["Json", "debugger.tabs", []],
   tabsBlackBoxed: ["Json", "debugger.tabsBlackBoxed", []],
@@ -110,16 +107,17 @@ const features = exports.features = new 
   codeCoverage: ["Bool", "code-coverage"],
   eventListeners: ["Bool", "event-listeners"],
   outline: ["Bool", "outline"],
   codeFolding: ["Bool", "code-folding"],
   replay: ["Bool", "replay"],
   pausePoints: ["Bool", "pause-points"],
   skipPausing: ["Bool", "skip-pausing"],
   autocompleteExpression: ["Bool", "autocomplete-expressions"],
-  mapExpressionBindings: ["Bool", "map-expression-bindings"]
+  mapExpressionBindings: ["Bool", "map-expression-bindings"],
+  componentPane: ["Bool", "component-pane"]
 });
 
 if (prefs.debuggerPrefsSchemaVersion !== prefsSchemaVersion) {
   // clear pending Breakpoints
   prefs.pendingBreakpoints = {};
   prefs.debuggerPrefsSchemaVersion = prefsSchemaVersion;
 }
\ No newline at end of file
--- a/devtools/client/preferences/debugger.js
+++ b/devtools/client/preferences/debugger.js
@@ -24,17 +24,16 @@ pref("devtools.debugger.prefs-schema-ver
 pref("devtools.debugger.ui.panes-workers-and-sources-width", 200);
 pref("devtools.debugger.ui.panes-instruments-width", 300);
 pref("devtools.debugger.ui.panes-visible-on-startup", false);
 pref("devtools.debugger.ui.variables-sorting-enabled", true);
 pref("devtools.debugger.ui.variables-only-enum-visible", false);
 pref("devtools.debugger.ui.variables-searchbox-visible", false);
 pref("devtools.debugger.ui.framework-grouping-on", true);
 pref("devtools.debugger.call-stack-visible", true);
-pref("devtools.debugger.component-stack-visible", true);
 pref("devtools.debugger.scopes-visible", true);
 pref("devtools.debugger.component-visible", true);
 pref("devtools.debugger.workers-visible", true);
 pref("devtools.debugger.breakpoints-visible", true);
 pref("devtools.debugger.expressions-visible", true);
 pref("devtools.debugger.start-panel-collapsed", false);
 pref("devtools.debugger.end-panel-collapsed", false);
 pref("devtools.debugger.tabs", "[]");
@@ -57,13 +56,13 @@ pref("devtools.debugger.features.map-sco
 pref("devtools.debugger.features.remove-command-bar-options", false);
 pref("devtools.debugger.features.workers", true);
 pref("devtools.debugger.features.code-coverage", false);
 pref("devtools.debugger.features.event-listeners", false);
 pref("devtools.debugger.features.code-folding", false);
 pref("devtools.debugger.features.outline", true);
 pref("devtools.debugger.features.replay", false);
 pref("devtools.debugger.features.pause-points", true);
-pref("devtools.debugger.features.component-stack", false);
+pref("devtools.debugger.features.component-pane", false);
 pref("devtools.debugger.features.async-stepping", true);
 pref("devtools.debugger.features.skip-pausing", true);
 pref("devtools.debugger.features.autocomplete-expressions", false);
 pref("devtools.debugger.features.map-expression-bindings", true);
--- a/devtools/client/shared/components/tabs/Tabs.js
+++ b/devtools/client/shared/components/tabs/Tabs.js
@@ -320,17 +320,17 @@ define(function(require, exports, module
               )
             )
           );
         });
 
       // Display the menu only if there is not enough horizontal
       // space for all tabs (and overflow happened).
       const allTabsMenu = this.state.overflow ? (
-        dom.div({
+        dom.button({
           className: "all-tabs-menu",
           onClick: this.props.onAllTabsMenuClick,
         })
       ) : null;
 
       // Get the sidebar toggle button if a renderSidebarToggle function is provided.
       const sidebarToggle =  this.props.renderSidebarToggle ?
         this.props.renderSidebarToggle() : null;
--- a/devtools/client/themes/common.css
+++ b/devtools/client/themes/common.css
@@ -750,32 +750,44 @@ checkbox:-moz-focusring {
 .all-tabs-menu {
   position: absolute;
 
   top: 0;
   inset-inline-end: 0;
   width: 15px;
   height: 100%;
 
+  padding: 0;
+  border: none;
   border-inline-start: 1px solid var(--theme-splitter-color);
 
   background: var(--theme-tab-toolbar-background);
   background-image: url("chrome://devtools/skin/images/dropmarker.svg");
   background-repeat: no-repeat;
   background-position: center;
+  -moz-context-properties: fill;
+  fill: var(--theme-toolbar-photon-icon-color);
+}
+
+.all-tabs-menu:hover {
+  background-color: var(--theme-toolbar-hover);
+}
+
+.all-tabs-menu:hover:active {
+  background-color: var(--theme-toolbar-hover-active);
 }
 
 .devtools-tab-line {
   position: absolute;
   top: 0;
   left: 0;
   width: 100%;
   height: 2px;
   background: transparent;
-  transition: transform 250ms var(--animation-easing-function), opacity 250ms var(--animation-easing-function);
+  transition: transform 250ms var(--animation-curve), opacity 250ms var(--animation-curve);
   opacity: 0;
   transform: scaleX(0);
 }
 
 .devtools-tab:hover .devtools-tab-line,
 .tabs-menu-item:hover .devtools-tab-line {
   background: var(--tab-line-hover-color);
   opacity: 1;
--- a/devtools/client/themes/images/dropmarker.svg
+++ b/devtools/client/themes/images/dropmarker.svg
@@ -1,6 +1,6 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
-   - License, v. 2.0. If a copy of the MPL was not distributed with this
-   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-<svg xmlns="http://www.w3.org/2000/svg" width="8" height="4" viewBox="0 0 8 4">
-  <polygon points="0,0 4,4 8,0" fill="#b6babf"/>
-</svg>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+   - License, v. 2.0. If a copy of the MPL was not distributed with this
+   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<svg xmlns="http://www.w3.org/2000/svg" width="8" height="4" viewBox="0 0 8 4">
+  <polygon points="0,0 4,4 8,0" fill="context-fill #b6babf"/>
+</svg>
--- a/devtools/server/actors/animation.js
+++ b/devtools/server/actors/animation.js
@@ -925,23 +925,16 @@ exports.AnimationsActor = protocol.Actor
   },
 
   /**
    * Pause given player synchronously.
    *
    * @param {Object} player
    */
   pauseSync(player) {
-    // Gecko includes an optimization that means that if the animation is play-pending
-    // and we set the startTime to null, the change will be ignored and the animation
-    // will continue to be play-pending. This violates the spec but until the spec is
-    // clarified[1] on this point we work around this by ensuring the animation's
-    // startTime is set to something non-null before setting it to null.
-    // [1] https://github.com/w3c/csswg-drafts/issues/2691
-    this.playSync(player);
     player.startTime = null;
   },
 
   /**
    * Play given player synchronously.
    *
    * @param {Object} player
    */
--- a/devtools/server/actors/highlighters/flexbox.js
+++ b/devtools/server/actors/highlighters/flexbox.js
@@ -40,17 +40,16 @@ const FLEXBOX_LINES_PROPERTIES = {
   }
 };
 
 const FLEXBOX_CONTAINER_PATTERN_WIDTH = 14; // px
 const FLEXBOX_CONTAINER_PATTERN_HEIGHT = 14; // px
 const FLEXBOX_JUSTIFY_CONTENT_PATTERN_WIDTH = 7; // px
 const FLEXBOX_JUSTIFY_CONTENT_PATTERN_HEIGHT = 7; // px
 const FLEXBOX_CONTAINER_PATTERN_LINE_DISH = [5, 3]; // px
-const BASIS_FILL_COLOR = "rgb(109, 184, 255, 0.4)";
 
 /**
  * Cached used by `FlexboxHighlighter.getFlexContainerPattern`.
  */
 const gCachedFlexboxPattern = new Map();
 
 const FLEXBOX = "flexbox";
 const JUSTIFY_CONTENT = "justify-content";
@@ -61,19 +60,16 @@ const JUSTIFY_CONTENT = "justify-content
  *
  * Available Options:
  * - color(colorValue)
  *     @param  {String} colorValue
  *     The color that should be used to draw the highlighter for this flexbox.
  * - showAlignment(isShown)
  *     @param  {Boolean} isShown
  *     Shows the alignment in the flexbox highlighter.
- * - showFlexBasis(isShown)
- *     @param  {Boolean} isShown
- *     Shows the flex basis in the flexbox highlighter.
  */
 class FlexboxHighlighter extends AutoRefreshHighlighter {
   constructor(highlighterEnv) {
     super(highlighterEnv);
 
     this.ID_CLASS_PREFIX = "flexbox-";
 
     this.markup = new CanvasFrameAnonymousContentHelper(this.highlighterEnv,
@@ -291,45 +287,39 @@ class FlexboxHighlighter extends AutoRef
     const oldFlexData = this.flexData;
     this.flexData = getFlexData(this.currentNode.getAsFlexContainer(), this.win);
     const hasFlexDataChanged = compareFlexData(oldFlexData, this.flexData);
 
     const oldAlignItems = this.alignItemsValue;
     this.alignItemsValue = this.computedStyle.alignItems;
     const newAlignItems = this.alignItemsValue;
 
-    const oldFlexBasis = this.flexBasis;
-    this.flexBasis = this.computedStyle.flexBasis;
-    const newFlexBasis = this.flexBasis;
-
     const oldFlexDirection = this.flexDirection;
     this.flexDirection = this.computedStyle.flexDirection;
     const newFlexDirection = this.flexDirection;
 
     const oldFlexWrap = this.flexWrap;
     this.flexWrap = this.computedStyle.flexWrap;
     const newFlexWrap = this.flexWrap;
 
     const oldJustifyContent = this.justifyContentValue;
     this.justifyContentValue = this.computedStyle.justifyContent;
     const newJustifyContent = this.justifyContentValue;
 
     return hasMoved ||
            hasFlexDataChanged ||
            oldAlignItems !== newAlignItems ||
-           oldFlexBasis !== newFlexBasis ||
            oldFlexDirection !== newFlexDirection ||
            oldFlexWrap !== newFlexWrap ||
            oldJustifyContent !== newJustifyContent;
   }
 
   _hide() {
     this.alignItemsValue = null;
     this.computedStyle = null;
-    this.flexBasis = null;
     this.flexData = null;
     this.flexDirection = null;
     this.flexWrap = null;
     this.justifyContentValue = null;
 
     setIgnoreLayoutChanges(true);
     this._hideFlexbox();
     setIgnoreLayoutChanges(false, this.highlighterEnv.document.documentElement);
@@ -537,38 +527,16 @@ class FlexboxHighlighter extends AutoRef
     const angleRad = Math.atan2(p2[1] - p1[1], p2[0] - p1[0]);
     this.ctx.rotate(angleRad);
 
     this.ctx.fill();
     this.ctx.stroke();
     this.ctx.restore();
   }
 
-  /**
-   * Renders the flex basis for a given flex item.
-   */
-  renderFlexItemBasis(flexItem, left, top, right, bottom, boundsWidth) {
-    if (!this.options.showFlexBasis || !this.computedStyle) {
-      return;
-    }
-
-    let basis = this.flexBasis;
-
-    if (basis.endsWith("px")) {
-      right = Math.round(left + parseFloat(basis));
-    } else if (basis.endsWith("%")) {
-      basis = parseFloat(basis) / 100 * boundsWidth;
-      right = Math.round(left + basis);
-    }
-
-    this.ctx.fillStyle = BASIS_FILL_COLOR;
-    drawRect(this.ctx, left, top, right, bottom, this.currentMatrix);
-    this.ctx.fill();
-  }
-
   renderFlexItems() {
     if (!this.flexData || !this.currentQuads.content || !this.currentQuads.content[0]) {
       return;
     }
 
     const { devicePixelRatio } = this.win;
     const lineWidth = getDisplayPixelRatio(this.win);
     const offset = (lineWidth / 2) % 1;
@@ -595,18 +563,16 @@ class FlexboxHighlighter extends AutoRef
         const left = Math.round(flexItemBounds.left - bounds.left);
         const top = Math.round(flexItemBounds.top - bounds.top);
         const right = Math.round(flexItemBounds.right - bounds.left);
         const bottom = Math.round(flexItemBounds.bottom - bounds.top);
 
         clearRect(this.ctx, left, top, right, bottom, this.currentMatrix);
         drawRect(this.ctx, left, top, right, bottom, this.currentMatrix);
         this.ctx.stroke();
-
-        this.renderFlexItemBasis(flexItem.node, left, top, right, bottom, bounds.width);
       }
     }
 
     this.ctx.restore();
   }
 
   renderFlexLines() {
     if (!this.flexData || !this.currentQuads.content || !this.currentQuads.content[0]) {
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -672,16 +672,17 @@ nsDocShell::LoadURI(nsIURI* aURI,
   // firing, so we call IsNavigationAllowed rather than just IsPrintingOrPP.
   if (!IsNavigationAllowed(true, false)) {
     return NS_OK; // JS may not handle returning of an error code
   }
 
   nsCOMPtr<nsIURI> referrer;
   nsCOMPtr<nsIURI> originalURI;
   Maybe<nsCOMPtr<nsIURI>> resultPrincipalURI;
+  bool keepResultPrincipalURIIfSet = false;
   bool loadReplace = false;
   nsCOMPtr<nsIInputStream> postStream;
   nsCOMPtr<nsIInputStream> headersStream;
   nsCOMPtr<nsIPrincipal> triggeringPrincipal;
   bool inheritPrincipal = false;
   bool principalIsExplicit = false;
   bool sendReferrer = true;
   uint32_t referrerPolicy = RP_Unset;
@@ -703,16 +704,17 @@ nsDocShell::LoadURI(nsIURI* aURI,
     StartupTimeline::RecordOnce(StartupTimeline::FIRST_LOAD_URI);
   }
 
   // Extract the info from the DocShellLoadInfo struct...
   if (aLoadInfo) {
     referrer = aLoadInfo->Referrer();
     originalURI = aLoadInfo->OriginalURI();
     aLoadInfo->GetMaybeResultPrincipalURI(resultPrincipalURI);
+    keepResultPrincipalURIIfSet = aLoadInfo->KeepResultPrincipalURIIfSet();
     loadReplace = aLoadInfo->LoadReplace();
     // Get the appropriate loadType from nsIDocShellLoadInfo type
     loadType = aLoadInfo->LoadType();
 
     triggeringPrincipal = aLoadInfo->TriggeringPrincipal();
     inheritPrincipal = aLoadInfo->InheritPrincipal();
     principalIsExplicit = aLoadInfo->PrincipalIsExplicit();
     shEntry = aLoadInfo->SHEntry();
@@ -996,16 +998,17 @@ nsDocShell::LoadURI(nsIURI* aURI,
 
   if (originalFrameSrc) {
     flags |= INTERNAL_LOAD_FLAGS_ORIGINAL_FRAME_SRC;
   }
 
   return InternalLoad(aURI,
                       originalURI,
                       resultPrincipalURI,
+                      keepResultPrincipalURIIfSet,
                       loadReplace,
                       referrer,
                       referrerPolicy,
                       triggeringPrincipal,
                       principalToInherit,
                       flags,
                       target,
                       nullptr,      // No type hint
@@ -4793,17 +4796,17 @@ nsDocShell::LoadErrorPage(nsIURI* aURI, 
   // end of the URL, so append it last.
   errorPageUrl.AppendLiteral("&d=");
   errorPageUrl.AppendASCII(escapedDescription.get());
 
   nsCOMPtr<nsIURI> errorPageURI;
   nsresult rv = NS_NewURI(getter_AddRefs(errorPageURI), errorPageUrl);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  return InternalLoad(errorPageURI, nullptr, Nothing(), false, nullptr, RP_Unset,
+  return InternalLoad(errorPageURI, nullptr, Nothing(), false, false, nullptr, RP_Unset,
                       nsContentUtils::GetSystemPrincipal(), nullptr,
                       INTERNAL_LOAD_FLAGS_NONE, EmptyString(),
                       nullptr, VoidString(), nullptr, nullptr,
                       LOAD_ERROR_PAGE, nullptr, true, VoidString(), this,
                       nullptr, nullptr, nullptr);
 }
 
 NS_IMETHODIMP
@@ -4888,16 +4891,17 @@ nsDocShell::Reload(uint32_t aReloadFlags
     uint32_t referrerPolicy = mReferrerPolicy;
 
     // Reload always rewrites result principal URI.
     Maybe<nsCOMPtr<nsIURI>> emplacedResultPrincipalURI;
     emplacedResultPrincipalURI.emplace(std::move(resultPrincipalURI));
     rv = InternalLoad(currentURI,
                       originalURI,
                       emplacedResultPrincipalURI,
+                      false,
                       loadReplace,
                       referrerURI,
                       referrerPolicy,
                       triggeringPrincipal,
                       triggeringPrincipal,
                       flags,
                       EmptyString(),   // No window target
                       NS_LossyConvertUTF16toASCII(contentTypeHint).get(),
@@ -6179,16 +6183,21 @@ nsDocShell::ForceRefreshURI(nsIURI* aURI
    */
   loadInfo->SetSendReferrer(false);
 
   /* for most refreshes the current URI is an appropriate
    * internal referrer
    */
   loadInfo->SetReferrer(mCurrentURI);
 
+  loadInfo->SetOriginalURI(mCurrentURI);
+  loadInfo->SetResultPrincipalURI(aURI);
+  loadInfo->SetResultPrincipalURIIsSome(true);
+  loadInfo->SetKeepResultPrincipalURIIfSet(true);
+
   // Set the triggering pricipal to aPrincipal if available, or current
   // document's principal otherwise.
   nsCOMPtr<nsIPrincipal> principal = aPrincipal;
   if (!principal) {
     nsCOMPtr<nsIDocument> doc = GetDocument();
     if (!doc) {
       return NS_ERROR_FAILURE;
     }
@@ -8998,16 +9007,17 @@ nsDocShell::CopyFavicon(nsIURI* aOldURI,
 
 class InternalLoadEvent : public Runnable
 {
 public:
   InternalLoadEvent(nsDocShell* aDocShell,
                     nsIURI* aURI,
                     nsIURI* aOriginalURI,
                     Maybe<nsCOMPtr<nsIURI>> const& aResultPrincipalURI,
+                    bool aKeepResultPrincipalURIIfSet,
                     bool aLoadReplace,
                     nsIURI* aReferrer, uint32_t aReferrerPolicy,
                     nsIPrincipal* aTriggeringPrincipal,
                     nsIPrincipal* aPrincipalToInherit,
                     uint32_t aFlags,
                     const char* aTypeHint,
                     nsIInputStream* aPostData,
                     nsIInputStream* aHeadersData,
@@ -9018,16 +9028,17 @@ public:
                     nsIDocShell* aSourceDocShell,
                     nsIURI* aBaseURI)
     : mozilla::Runnable("InternalLoadEvent")
     , mSrcdoc(aSrcdoc)
     , mDocShell(aDocShell)
     , mURI(aURI)
     , mOriginalURI(aOriginalURI)
     , mResultPrincipalURI(aResultPrincipalURI)
+    , mKeepResultPrincipalURIIfSet(aKeepResultPrincipalURIIfSet)
     , mLoadReplace(aLoadReplace)
     , mReferrer(aReferrer)
     , mReferrerPolicy(aReferrerPolicy)
     , mTriggeringPrincipal(aTriggeringPrincipal)
     , mPrincipalToInherit(aPrincipalToInherit)
     , mPostData(aPostData)
     , mHeadersData(aHeadersData)
     , mSHEntry(aSHEntry)
@@ -9044,16 +9055,17 @@ public:
       mTypeHint.SetIsVoid(true);
     }
   }
 
   NS_IMETHOD
   Run() override
   {
     return mDocShell->InternalLoad(mURI, mOriginalURI, mResultPrincipalURI,
+                                   mKeepResultPrincipalURIIfSet,
                                    mLoadReplace,
                                    mReferrer,
                                    mReferrerPolicy,
                                    mTriggeringPrincipal, mPrincipalToInherit,
                                    mFlags, EmptyString(),
                                    mTypeHint.IsVoid() ? nullptr
                                                       : mTypeHint.get(),
                                    VoidString(), mPostData,
@@ -9066,16 +9078,17 @@ public:
 private:
   nsCString mTypeHint;
   nsString mSrcdoc;
 
   RefPtr<nsDocShell> mDocShell;
   nsCOMPtr<nsIURI> mURI;
   nsCOMPtr<nsIURI> mOriginalURI;
   Maybe<nsCOMPtr<nsIURI>> mResultPrincipalURI;
+  bool mKeepResultPrincipalURIIfSet;
   bool mLoadReplace;
   nsCOMPtr<nsIURI> mReferrer;
   uint32_t mReferrerPolicy;
   nsCOMPtr<nsIPrincipal> mTriggeringPrincipal;
   nsCOMPtr<nsIPrincipal> mPrincipalToInherit;
   nsCOMPtr<nsIInputStream> mPostData;
   nsCOMPtr<nsIInputStream> mHeadersData;
   nsCOMPtr<nsISHEntry> mSHEntry;
@@ -9112,16 +9125,17 @@ nsDocShell::CreatePrincipalFromReferrer(
 
   return *aResult ? NS_OK : NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsDocShell::InternalLoad(nsIURI* aURI,
                          nsIURI* aOriginalURI,
                          Maybe<nsCOMPtr<nsIURI>> const& aResultPrincipalURI,
+                         bool aKeepResultPrincipalURIIfSet,
                          bool aLoadReplace,
                          nsIURI* aReferrer,
                          uint32_t aReferrerPolicy,
                          nsIPrincipal* aTriggeringPrincipal,
                          nsIPrincipal* aPrincipalToInherit,
                          uint32_t aFlags,
                          const nsAString& aWindowTarget,
                          const char* aTypeHint,
@@ -9410,16 +9424,17 @@ nsDocShell::InternalLoad(nsIURI* aURI,
         // Set up our loadinfo so it will do the load as much like we would have
         // as possible.
         loadInfo->SetReferrer(aReferrer);
         loadInfo->SetReferrerPolicy((mozilla::net::ReferrerPolicy)aReferrerPolicy);
         loadInfo->SetSendReferrer(!(aFlags &
                                     INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER));
         loadInfo->SetOriginalURI(aOriginalURI);
         loadInfo->SetMaybeResultPrincipalURI(aResultPrincipalURI);
+        loadInfo->SetKeepResultPrincipalURIIfSet(aKeepResultPrincipalURIIfSet);
         loadInfo->SetLoadReplace(aLoadReplace);
         loadInfo->SetTriggeringPrincipal(aTriggeringPrincipal);
         loadInfo->SetInheritPrincipal(
           aFlags & INTERNAL_LOAD_FLAGS_INHERIT_PRINCIPAL);
         // Explicit principal because we do not want any guesses as to what the
         // principal to inherit is: it should be aTriggeringPrincipal.
         loadInfo->SetPrincipalIsExplicit(true);
         loadInfo->SetLoadType(LOAD_LINK);
@@ -9459,16 +9474,17 @@ nsDocShell::InternalLoad(nsIURI* aURI,
     //
     // Transfer the load to the target DocShell...  Pass nullptr as the
     // window target name from to prevent recursive retargeting!
     //
     if (NS_SUCCEEDED(rv) && targetDocShell) {
       rv = targetDocShell->InternalLoad(aURI,
                                         aOriginalURI,
                                         aResultPrincipalURI,
+                                        aKeepResultPrincipalURIIfSet,
                                         aLoadReplace,
                                         aReferrer,
                                         aReferrerPolicy,
                                         aTriggeringPrincipal,
                                         principalToInherit,
                                         aFlags,
                                         EmptyString(),   // No window target
                                         aTypeHint,
@@ -9557,16 +9573,17 @@ nsDocShell::InternalLoad(nsIURI* aURI,
       // create extra history entries.
       if (LOAD_TYPE_HAS_FLAGS(aLoadType, LOAD_FLAGS_REPLACE_HISTORY)) {
         mLoadType = LOAD_NORMAL_REPLACE;
       }
 
       // Do this asynchronously
       nsCOMPtr<nsIRunnable> ev =
         new InternalLoadEvent(this, aURI, aOriginalURI, aResultPrincipalURI,
+                              aKeepResultPrincipalURIIfSet,
                               aLoadReplace, aReferrer, aReferrerPolicy,
                               aTriggeringPrincipal, principalToInherit,
                               aFlags, aTypeHint, aPostData,
                               aHeadersData, aLoadType, aSHEntry, aFirstParty,
                               aSrcdoc, aSourceDocShell, aBaseURI);
       return DispatchToTabGroup(TaskCategory::Other, ev.forget());
     }
 
@@ -10074,17 +10091,18 @@ nsDocShell::InternalLoad(nsIURI* aURI,
   attrs.SetFirstPartyDomain(isTopLevelDoc, aURI);
 
   PredictorLearn(aURI, nullptr,
                  nsINetworkPredictor::LEARN_LOAD_TOPLEVEL, attrs);
   PredictorPredict(aURI, nullptr,
                    nsINetworkPredictor::PREDICT_LOAD, attrs, nullptr);
 
   nsCOMPtr<nsIRequest> req;
-  rv = DoURILoad(aURI, aOriginalURI, aResultPrincipalURI, aLoadReplace,
+  rv = DoURILoad(aURI, aOriginalURI, aResultPrincipalURI,
+                 aKeepResultPrincipalURIIfSet, aLoadReplace,
                  loadFromExternal,
                  (aFlags & INTERNAL_LOAD_FLAGS_FORCE_ALLOW_DATA_URI),
                  (aFlags & INTERNAL_LOAD_FLAGS_ORIGINAL_FRAME_SRC),
                  aReferrer,
                  !(aFlags & INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER),
                  aReferrerPolicy,
                  aTriggeringPrincipal, principalToInherit, aTypeHint,
                  aFileName, aPostData, aHeadersData,
@@ -10214,16 +10232,17 @@ IsConsideredSameOriginForUIR(nsIPrincipa
 
   return aTriggeringPrincipal->Equals(tmpResultPrincipal);
 }
 
 nsresult
 nsDocShell::DoURILoad(nsIURI* aURI,
                       nsIURI* aOriginalURI,
                       Maybe<nsCOMPtr<nsIURI>> const& aResultPrincipalURI,
+                      bool aKeepResultPrincipalURIIfSet,
                       bool aLoadReplace,
                       bool aLoadFromExternal,
                       bool aForceAllowDataURI,
                       bool aOriginalFrameSrc,
                       nsIURI* aReferrerURI,
                       bool aSendReferrer,
                       uint32_t aReferrerPolicy,
                       nsIPrincipal* aTriggeringPrincipal,
@@ -10563,17 +10582,20 @@ nsDocShell::DoURILoad(nsIURI* aURI,
       channel->GetLoadFlags(&loadFlags);
       NS_ENSURE_SUCCESS(rv, rv);
       channel->SetLoadFlags(loadFlags | nsIChannel::LOAD_REPLACE);
     }
   } else {
     channel->SetOriginalURI(aURI);
   }
 
-  if (aResultPrincipalURI) {
+  nsCOMPtr<nsIURI> rpURI;
+  loadInfo->GetResultPrincipalURI(getter_AddRefs(rpURI));
+  if (aResultPrincipalURI &&
+      (!aKeepResultPrincipalURIIfSet || !rpURI)) {
     // Unconditionally override, we want the replay to be equal to what has
     // been captured.
     loadInfo->SetResultPrincipalURI(aResultPrincipalURI.ref());
   }
 
   if (aTypeHint && *aTypeHint) {
     channel->SetContentType(nsDependentCString(aTypeHint));
     mContentTypeHint = aTypeHint;
@@ -12140,16 +12162,17 @@ nsDocShell::LoadHistoryEntry(nsISHEntry*
   // aSourceDocShell was introduced. According to spec we should be passing
   // the source browsing context that was used when the history entry was
   // first created. bug 947716 has been created to address this issue.
   Maybe<nsCOMPtr<nsIURI>> emplacedResultPrincipalURI;
   emplacedResultPrincipalURI.emplace(std::move(resultPrincipalURI));
   rv = InternalLoad(uri,
                     originalURI,
                     emplacedResultPrincipalURI,
+                    false,
                     loadReplace,
                     referrerURI,
                     referrerPolicy,
                     triggeringPrincipal,
                     principalToInherit,
                     flags,
                     EmptyString(),      // No window target
                     contentType.get(),  // Type hint
@@ -13419,16 +13442,17 @@ nsDocShell::OnLinkClickSync(nsIContent* 
 
   if (aIsUserTriggered) {
     flags |= INTERNAL_LOAD_FLAGS_IS_USER_TRIGGERED;
   }
 
   nsresult rv = InternalLoad(aURI,                      // New URI
                              nullptr,                   // Original URI
                              Nothing(),                 // Let the protocol handler assign it
+                             false,
                              false,                     // LoadReplace
                              referer,                   // Referer URI
                              refererPolicy,             // Referer policy
                              triggeringPrincipal,
                              aContent->NodePrincipal(),
                              flags,
                              target,                    // Window target
                              NS_LossyConvertUTF16toASCII(typeHint).get(),
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -515,16 +515,17 @@ private: // member functions
   // If aSrcdoc is not void, the load will be considered as a srcdoc load,
   // and the contents of aSrcdoc will be loaded instead of aURI.
   // aOriginalURI will be set as the originalURI on the channel that does the
   // load. If aOriginalURI is null, aURI will be set as the originalURI.
   // If aLoadReplace is true, LOAD_REPLACE flag will be set to the nsIChannel.
   nsresult DoURILoad(nsIURI* aURI,
                      nsIURI* aOriginalURI,
                      mozilla::Maybe<nsCOMPtr<nsIURI>> const& aResultPrincipalURI,
+                     bool aKeepResultPrincipalURIIfSet,
                      bool aLoadReplace,
                      bool aLoadFromExternal,
                      bool aForceAllowDataURI,
                      bool aOriginalFrameSrc,
                      nsIURI* aReferrer,
                      bool aSendReferrer,
                      uint32_t aReferrerPolicy,
                      nsIPrincipal* aTriggeringPrincipal,
--- a/docshell/base/nsDocShellLoadInfo.cpp
+++ b/docshell/base/nsDocShellLoadInfo.cpp
@@ -15,16 +15,17 @@
 
 namespace mozilla {
 
 
 } // mozilla
 
 nsDocShellLoadInfo::nsDocShellLoadInfo()
   : mResultPrincipalURIIsSome(false)
+  , mKeepResultPrincipalURIIfSet(false)
   , mLoadReplace(false)
   , mInheritPrincipal(false)
   , mPrincipalIsExplicit(false)
   , mForceAllowDataURI(false)
   , mOriginalFrameSrc(false)
   , mSendReferrer(true)
   , mReferrerPolicy(mozilla::net::RP_Unset)
   , mLoadType(LOAD_NORMAL)
@@ -80,16 +81,28 @@ nsDocShellLoadInfo::ResultPrincipalURIIs
 
 void
 nsDocShellLoadInfo::SetResultPrincipalURIIsSome(bool aIsSome)
 {
   mResultPrincipalURIIsSome = aIsSome;
 }
 
 bool
+nsDocShellLoadInfo::KeepResultPrincipalURIIfSet() const
+{
+  return mKeepResultPrincipalURIIfSet;
+}
+
+void
+nsDocShellLoadInfo::SetKeepResultPrincipalURIIfSet(bool aKeep)
+{
+  mKeepResultPrincipalURIIfSet = aKeep;
+}
+
+bool
 nsDocShellLoadInfo::LoadReplace() const
 {
   return mLoadReplace;
 }
 
 void
 nsDocShellLoadInfo::SetLoadReplace(bool aLoadReplace)
 {
--- a/docshell/base/nsDocShellLoadInfo.h
+++ b/docshell/base/nsDocShellLoadInfo.h
@@ -40,16 +40,20 @@ public:
   nsIURI* ResultPrincipalURI() const;
 
   void SetResultPrincipalURI(nsIURI* aResultPrincipalURI);
 
   bool ResultPrincipalURIIsSome() const;
 
   void SetResultPrincipalURIIsSome(bool aIsSome);
 
+  bool KeepResultPrincipalURIIfSet() const;
+
+  void SetKeepResultPrincipalURIIfSet(bool aKeep);
+
   bool LoadReplace() const;
 
   void SetLoadReplace(bool aLoadReplace);
 
   nsIPrincipal* TriggeringPrincipal() const;
 
   void SetTriggeringPrincipal(nsIPrincipal* aTriggeringPrincipal);
 
@@ -135,16 +139,20 @@ protected:
   nsCOMPtr<nsIURI> mResultPrincipalURI;
   bool mResultPrincipalURIIsSome;
 
   // The principal of the load, that is, the entity responsible for causing the
   // load to occur. In most cases the referrer and the triggeringPrincipal's URI
   // will be identical.
   nsCOMPtr<nsIPrincipal> mTriggeringPrincipal;
 
+  // if http-equiv="refresh" cause reload we do not want to replace
+  // ResultPrinicpalURI if it was already set.
+  bool mKeepResultPrincipalURIIfSet;
+
   // loadReplace flag to be passed to nsIDocShell.internalLoad.
   bool mLoadReplace;
 
   // If this attribute is true and no triggeringPrincipal is specified,
   // copy the principal from the referring document.
   bool mInheritPrincipal;
 
   // If this attribute is true only ever use the principal specified
--- a/docshell/base/nsIDocShell.idl
+++ b/docshell/base/nsIDocShell.idl
@@ -127,16 +127,23 @@ interface nsIDocShell : nsIDocShellTreeI
    * @param aURI                 - The URI to load.
    * @param aOriginalURI         - The URI to set as the originalURI on the channel
    *                               that does the load. If null, aURI will be set as
    *                               the originalURI.
    * @param aResultPrincipalURI  - The URI to be set to loadInfo.resultPrincipalURI
    *                               When Nothing, there will be no change
    *                               When Some, the principal URI will overwrite even
    *                               with a null value.
+   * @param aKeepResultPrincipalURIIfSet - If a refresh is caused by
+   *                                       http-equiv="refresh" we want to set
+   *                                       aResultPrincipalURI, but we do not want
+   *                                       to overwrite the channel's
+   *                                       ResultPrincipalURI, if it has already
+   *                                       been set on the channel by a protocol
+   *                                       handler.
    * @param aLoadReplace         - If set LOAD_REPLACE flag will be set on the
    *                               channel. aOriginalURI is null, this argument is
    *                               ignored.
    * @param aReferrer            - Referring URI
    * @param aReferrerPolicy      - Referrer policy
    * @param aTriggeringPrincipal - A non-null principal that initiated that load.
    *                               Please note that this is the principal that is
    *                               used for security checks. If the argument aURI
@@ -175,16 +182,17 @@ interface nsIDocShell : nsIDocShellTreeI
    * @param aSourceDocShell      - The source browsing context for the navigation.
    * @param aBaseURI             - The base URI to be used for the load.  Set in
    *                               srcdoc loads as it cannot otherwise be inferred
    *                               in certain situations such as view-source.
    */
   [noscript]void internalLoad(in nsIURI aURI,
                               in nsIURI aOriginalURI,
                               [const] in MaybeURI aResultPrincipalURI,
+                              in bool aKeepResultPrincipalURIIfSet,
                               in boolean aLoadReplace,
                               in nsIURI aReferrer,
                               in unsigned long aReferrerPolicy,
                               in nsIPrincipal aTriggeringPrincipal,
                               in nsIPrincipal aPrincipalToInherit,
                               in uint32_t aFlags,
                               in AString aWindowTarget,
                               in string aTypeHint,
--- a/dom/animation/Animation.cpp
+++ b/dom/animation/Animation.cpp
@@ -222,17 +222,21 @@ Animation::SetTimelineNoUpdate(Animation
   }
   UpdateTiming(SeekFlag::NoSeek, SyncNotifyFlag::Async);
 }
 
 // https://drafts.csswg.org/web-animations/#set-the-animation-start-time
 void
 Animation::SetStartTime(const Nullable<TimeDuration>& aNewStartTime)
 {
-  if (aNewStartTime == mStartTime) {
+  // Return early if the start time will not change. However, if we
+  // are pending, then setting the start time to any value
+  // including the current value has the effect of aborting
+  // pending tasks so we should not return early in that case.
+  if (!Pending() && aNewStartTime == mStartTime) {
     return;
   }
 
   AutoMutationBatchForAnimation mb(*this);
 
   Nullable<TimeDuration> timelineTime;
   if (mTimeline) {
     // The spec says to check if the timeline is active (has a resolved time)
--- a/dom/base/Attr.cpp
+++ b/dom/base/Attr.cpp
@@ -21,16 +21,17 @@
 #include "nsIDocument.h"
 #include "nsGkAtoms.h"
 #include "nsCOMArray.h"
 #include "nsNameSpaceManager.h"
 #include "nsNodeUtils.h"
 #include "nsTextNode.h"
 #include "mozAutoDocUpdate.h"
 #include "nsWrapperCacheInlines.h"
+#include "NodeUbiReporting.h"
 
 namespace mozilla {
 namespace dom {
 
 //----------------------------------------------------------------------
 bool Attr::sInitialized;
 
 Attr::Attr(nsDOMAttributeMap *aAttrMap,
@@ -303,10 +304,16 @@ Attr::Shutdown()
 }
 
 JSObject*
 Attr::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
   return Attr_Binding::Wrap(aCx, this, aGivenProto);
 }
 
+void
+Attr::ConstructUbiNode(void* storage)
+{
+  JS::ubi::Concrete<Attr>::construct(storage, this);
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/base/Attr.h
+++ b/dom/base/Attr.h
@@ -46,16 +46,18 @@ public:
                                       nsIPrincipal* aSubjectPrincipal,
                                       ErrorResult& aError) override;
   virtual void GetNodeValueInternal(nsAString& aNodeValue) override;
   virtual void SetNodeValueInternal(const nsAString& aNodeValue,
                                     ErrorResult& aError) override;
 
   void GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
 
+  void ConstructUbiNode(void* storage) override;
+
   nsDOMAttributeMap* GetMap()
   {
     return mAttrMap;
   }
 
   void SetMap(nsDOMAttributeMap *aMap);
 
   Element* GetElement() const;
--- a/dom/base/FragmentOrElement.cpp
+++ b/dom/base/FragmentOrElement.cpp
@@ -120,16 +120,18 @@
 #include "mozilla/dom/HTMLTemplateElement.h"
 #include "mozilla/dom/SVGUseElement.h"
 
 #include "nsStyledElement.h"
 #include "nsIContentInlines.h"
 #include "nsChildContentList.h"
 #include "mozilla/BloomFilter.h"
 
+#include "NodeUbiReporting.h"
+
 using namespace mozilla;
 using namespace mozilla::dom;
 
 int32_t nsIContent::sTabFocusModel = eTabFocus_any;
 bool nsIContent::sTabFocusModelAppliesToXUL = false;
 uint64_t nsMutationGuard::sGeneration = 0;
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsIContent)
@@ -440,16 +442,22 @@ nsIContent::GetURLDataForStyleAttr(nsIPr
                                        OwnerDoc()->GetDocumentURI(),
                                        aSubjectPrincipal);
   }
   // This also ignores the case that SVG inside XBL binding.
   // But it is probably fine.
   return do_AddRef(OwnerDoc()->DefaultStyleAttrURLData());
 }
 
+void
+nsIContent::ConstructUbiNode(void* storage)
+{
+  JS::ubi::Concrete<nsIContent>::construct(storage, this);
+}
+
 //----------------------------------------------------------------------
 
 static inline JSObject*
 GetJSObjectChild(nsWrapperCache* aCache)
 {
   return aCache->PreservingWrapper() ? aCache->GetWrapperPreserveColor() : nullptr;
 }
 
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -25,16 +25,17 @@
 #include "nsICachingChannel.h"
 #include "nsIWebContentHandlerRegistrar.h"
 #include "nsICookiePermission.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsCharSeparatedTokenizer.h"
 #include "nsContentUtils.h"
 #include "nsUnicharUtils.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/StaticPrefs.h"
 #include "mozilla/Telemetry.h"
 #include "BatteryManager.h"
 #include "mozilla/dom/CredentialsContainer.h"
 #include "mozilla/dom/GamepadServiceTest.h"
 #include "mozilla/dom/MediaCapabilities.h"
 #include "mozilla/dom/WakeLock.h"
 #include "mozilla/dom/power/PowerManagerService.h"
 #include "mozilla/dom/MIDIAccessManager.h"
@@ -514,19 +515,18 @@ Navigator::Storage()
 
 // Values for the network.cookie.cookieBehavior pref are documented in
 // nsCookieService.cpp.
 #define COOKIE_BEHAVIOR_REJECT 2
 
 bool
 Navigator::CookieEnabled()
 {
-  bool cookieEnabled =
-    (Preferences::GetInt("network.cookie.cookieBehavior",
-                         COOKIE_BEHAVIOR_REJECT) != COOKIE_BEHAVIOR_REJECT);
+  bool cookieEnabled = (StaticPrefs::network_cookie_cookieBehavior() !=
+                        COOKIE_BEHAVIOR_REJECT);
 
   // Check whether an exception overrides the global cookie behavior
   // Note that the code for getting the URI here matches that in
   // nsHTMLDocument::SetCookie.
   if (!mWindow || !mWindow->GetDocShell()) {
     return cookieEnabled;
   }
 
new file mode 100644
--- /dev/null
+++ b/dom/base/NodeUbiReporting.cpp
@@ -0,0 +1,75 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sts=4 et sw=4 tw=99:
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "NodeUbiReporting.h"
+#include "js/UbiNodeUtils.h"
+#include "nsWindowSizes.h"
+
+using JS::ubi::SimpleEdgeRange;
+using JS::ubi::EdgeRange;
+
+const char16_t JS::ubi::Concrete<nsIDocument>::concreteTypeName[] = u"nsIDocument";
+const char16_t JS::ubi::Concrete<nsIContent>::concreteTypeName[] = u"nsIContent";
+const char16_t JS::ubi::Concrete<Attr>::concreteTypeName[] = u"Attr";
+
+void
+JS::ubi::Concrete<nsINode>::construct(void* storage, nsINode* ptr)
+{
+  // nsINode is abstract, and all of its inherited instances have
+  // an overridden function with instructions to construct ubi::Nodes.
+  // We actually want to call that function and construct from those instances.
+  ptr->ConstructUbiNode(storage);
+}
+
+js::UniquePtr<EdgeRange>
+JS::ubi::Concrete<nsINode>::edges(JSContext* cx, bool wantNames) const
+{
+  AutoSuppressGCAnalysis suppress;
+  auto range = js::MakeUnique<SimpleEdgeRange>();
+  if (!range) {
+    return nullptr;
+  }
+  if (get().GetParent()) {
+    char16_t* edgeName = nullptr;
+    if (wantNames) {
+      edgeName = NS_strdup(u"Parent Node");
+    }
+    if (!range->addEdge(JS::ubi::Edge(edgeName, get().GetParent()))) {
+      return nullptr;
+    }
+  }
+  for (auto curr = get().GetFirstChild(); curr; curr = curr->GetNextSibling()) {
+    char16_t* edgeName = nullptr;
+    if (wantNames) {
+      edgeName = NS_strdup(u"Child Node");
+    }
+    if (!range->addEdge(JS::ubi::Edge(edgeName, curr))) {
+      return nullptr;
+    }
+  }
+  return range;
+}
+
+JS::ubi::Node::Size
+JS::ubi::Concrete<nsINode>::size(mozilla::MallocSizeOf mallocSizeOf) const
+{
+  AutoSuppressGCAnalysis suppress;
+  mozilla::SizeOfState sz(mallocSizeOf);
+  nsWindowSizes wn(sz);
+  size_t n = 0;
+  get().AddSizeOfIncludingThis(wn, &n);
+  return n;
+}
+
+JS::ubi::Node::Size
+JS::ubi::Concrete<nsIDocument>::size(mozilla::MallocSizeOf mallocSizeOf) const
+{
+  AutoSuppressGCAnalysis suppress;
+  mozilla::SizeOfState sz(mallocSizeOf);
+  nsWindowSizes wn(sz);
+  getDoc().DocAddSizeOfIncludingThis(wn);
+  return wn.getTotalSize();
+}
new file mode 100644
--- /dev/null
+++ b/dom/base/NodeUbiReporting.h
@@ -0,0 +1,84 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sts=4 et sw=4 tw=99:
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef dom_NodeUbiReporting_h
+#define dom_NodeUbiReporting_h
+
+#include "nsINode.h"
+#include "js/UbiNode.h"
+
+/*
+ * This file defines specializations of JS::ubi::Concrete for DOM nodes
+ * so that the JS memory tools, which operate on the UbiNode graph, can
+ * define subclasses of JS::ubi::Base that represent DOM nodes and
+ * yield the outgoing edges in a DOM node graph for reporting.
+*/
+
+using mozilla::dom::Attr;
+
+namespace JS {
+namespace ubi {
+
+// The DOM node base class.
+// This is an abstract class and therefore does not require a concreteTypeName.
+template<>
+class Concrete<nsINode> : public Base
+{
+protected:
+  explicit Concrete(nsINode *ptr) : Base(ptr) { }
+
+public:
+  static void construct(void *storage, nsINode *ptr);
+  Size size(mozilla::MallocSizeOf mallocSizeOf) const override;
+  js::UniquePtr<EdgeRange> edges(JSContext* cx, bool wantNames) const override;
+
+  nsINode& get() const { return *static_cast<nsINode*>(ptr); }
+  CoarseType coarseType() const final { return CoarseType::Other; }
+};
+
+template<>
+class Concrete<nsIContent> : public Concrete<nsINode>
+{
+protected:
+  explicit Concrete(nsIContent *ptr) : Concrete<nsINode>(ptr) { }
+
+public:
+  static void construct(void *storage, nsIContent *ptr) { new (storage) Concrete(ptr); }
+  const char16_t* typeName() const override { return concreteTypeName; };
+  static const char16_t concreteTypeName[];
+};
+
+template<>
+class Concrete<nsIDocument> : public Concrete<nsINode>
+{
+protected:
+  explicit Concrete(nsIDocument *ptr) : Concrete<nsINode>(ptr) { }
+
+public:
+  static void construct(void *storage, nsIDocument *ptr) { new (storage) Concrete(ptr); }
+  Size size(mozilla::MallocSizeOf mallocSizeOf) const override;
+
+  nsIDocument& getDoc() const { return *static_cast<nsIDocument*>(ptr); }
+  const char16_t* typeName() const override { return concreteTypeName; };
+  static const char16_t concreteTypeName[];
+};
+
+template<>
+class Concrete<Attr> : public Concrete<nsINode>
+{
+protected:
+  explicit Concrete(Attr *ptr) : Concrete<nsINode>(ptr) { }
+
+public:
+  static void construct(void *storage, Attr *ptr) { new (storage) Concrete(ptr); }
+  const char16_t* typeName() const override { return concreteTypeName; };
+  static const char16_t concreteTypeName[];
+};
+
+} //namespace ubi
+} //namespace JS
+
+#endif
--- a/dom/base/ScreenLuminance.h
+++ b/dom/base/ScreenLuminance.h
@@ -4,16 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_ScreenLuminance_h
 #define mozilla_dom_ScreenLuminance_h
 
 #include "nsCycleCollectionParticipant.h"
 #include "nsISupportsImpl.h"
+#include "nsWrapperCache.h"
 
 class nsScreen;
 
 namespace mozilla {
 namespace dom {
 
 class ScreenLuminance final : public nsWrapperCache
 {
--- a/dom/base/moz.build
+++ b/dom/base/moz.build
@@ -33,16 +33,17 @@ XPIDL_SOURCES += [
 XPIDL_MODULE = 'dom'
 
 EXPORTS += [
     'AutocompleteFieldList.h',
     'Crypto.h',
     'HTMLSplitOnSpacesTokenizer.h',
     'IframeSandboxKeywordList.h',
     'mozAutoDocUpdate.h',
+    'NodeUbiReporting.h',
     'nsAttrAndChildArray.h',
     'nsAttrName.h',
     'nsAttrValue.h',
     'nsAttrValueInlines.h',
     'nsCaseTreatment.h',
     'nsChildContentList.h',
     'nsContentCID.h',
     'nsContentCreatorFunctions.h',
@@ -282,16 +283,17 @@ UNIFIED_SOURCES += [
     'MessageBroadcaster.cpp',
     'MessageListenerManager.cpp',
     'MessageManagerGlobal.cpp',
     'MessageSender.cpp',
     'MozQueryInterface.cpp',
     'Navigator.cpp',
     'NodeInfo.cpp',
     'NodeIterator.cpp',
+    'NodeUbiReporting.cpp',
     'nsAttrAndChildArray.cpp',
     'nsAttrValue.cpp',
     'nsAttrValueOrString.cpp',
     'nsCCUncollectableMarker.cpp',
     'nsContentAreaDragDrop.cpp',
     'nsContentIterator.cpp',
     'nsContentList.cpp',
     'nsContentPermissionHelper.cpp',
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -321,17 +321,16 @@ int32_t nsContentUtils::sPrivacyMaxInner
 int32_t nsContentUtils::sPrivacyMaxInnerHeight = 1000;
 
 nsContentUtils::UserInteractionObserver*
 nsContentUtils::sUserInteractionObserver = nullptr;
 
 uint32_t nsContentUtils::sHandlingInputTimeout = 1000;
 
 uint32_t nsContentUtils::sCookiesLifetimePolicy = nsICookieService::ACCEPT_NORMALLY;
-uint32_t nsContentUtils::sCookiesBehavior = nsICookieService::BEHAVIOR_ACCEPT;
 
 nsHtml5StringParser* nsContentUtils::sHTMLFragmentParser = nullptr;
 nsIParser* nsContentUtils::sXMLFragmentParser = nullptr;
 nsIFragmentContentSink* nsContentUtils::sXMLFragmentSink = nullptr;
 bool nsContentUtils::sFragmentParsingActive = false;
 
 bool nsContentUtils::sDoNotTrackEnabled = false;
 
@@ -684,20 +683,16 @@ nsContentUtils::Init()
 
   Preferences::AddBoolVarCache(&sSendPerformanceTimingNotifications,
                                "dom.performance.enable_notify_performance_timing", false);
 
   Preferences::AddUintVarCache(&sCookiesLifetimePolicy,
                                "network.cookie.lifetimePolicy",
                                nsICookieService::ACCEPT_NORMALLY);
 
-  Preferences::AddUintVarCache(&sCookiesBehavior,
-                               "network.cookie.cookieBehavior",
-                               nsICookieService::BEHAVIOR_ACCEPT);
-
   Preferences::AddBoolVarCache(&sDoNotTrackEnabled,
                                "privacy.donottrackheader.enabled", false);
 
   Preferences::AddBoolVarCache(&sUseActivityCursor,
                                "ui.use_activity_cursor", false);
 
   Preferences::AddBoolVarCache(&sAnimationsAPICoreEnabled,
                                "dom.animations-api.core.enabled", false);
@@ -8778,17 +8773,17 @@ nsContentUtils::StorageAllowedForPrincip
 
 // static, private
 void
 nsContentUtils::GetCookieBehaviorForPrincipal(nsIPrincipal* aPrincipal,
                                               uint32_t* aLifetimePolicy,
                                               uint32_t* aBehavior)
 {
   *aLifetimePolicy = sCookiesLifetimePolicy;
-  *aBehavior = sCookiesBehavior;
+  *aBehavior = StaticPrefs::network_cookie_cookieBehavior();
 
   // Any permissions set for the given principal will override our default
   // settings from preferences.
   nsCOMPtr<nsIPermissionManager> permissionManager =
     services::GetPermissionManager();
   if (!permissionManager) {
     return;
   }
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -3421,17 +3421,16 @@ private:
   static bool sShowInputPlaceholderOnFocus;
   static bool sAutoFocusEnabled;
 #ifndef RELEASE_OR_BETA
   static bool sBypassCSSOMOriginCheck;
 #endif
   static bool sIsBytecodeCacheEnabled;
   static int32_t sBytecodeCacheStrategy;
   static uint32_t sCookiesLifetimePolicy;
-  static uint32_t sCookiesBehavior;
   static bool sShortcutsCustomized;
 
   static int32_t sPrivacyMaxInnerWidth;
   static int32_t sPrivacyMaxInnerHeight;
 
   class UserInteractionObserver;
   static UserInteractionObserver* sUserInteractionObserver;
 
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -270,16 +270,17 @@
 #include "mozilla/MediaManager.h"
 
 #include "nsIURIClassifier.h"
 #include "nsIURIMutator.h"
 #include "mozilla/DocumentStyleRootIterator.h"
 #include "mozilla/RestyleManager.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "nsHTMLTags.h"
+#include "NodeUbiReporting.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 typedef nsTArray<Link*> LinkArray;
 
 static LazyLogModule gDocumentLeakPRLog("DocumentLeak");
 static LazyLogModule gCspPRLog("CSP");
@@ -1571,16 +1572,23 @@ nsIDocument::IsAboutPage() const
   principal->GetURI(getter_AddRefs(uri));
   bool isAboutScheme = true;
   if (uri) {
     uri->SchemeIs("about", &isAboutScheme);
   }
   return isAboutScheme;
 }
 
+void
+nsIDocument::ConstructUbiNode(void* storage)
+{
+  JS::ubi::Concrete<nsIDocument>::construct(storage, this);
+}
+
+
 nsDocument::~nsDocument()
 {
   MOZ_LOG(gDocumentLeakPRLog, LogLevel::Debug, ("DOCUMENT %p destroyed", this));
 
   NS_ASSERTION(!mIsShowing, "Destroying a currently-showing document");
 
   if (IsTopLevelContentDocument()) {
     //don't report for about: pages
--- a/dom/base/nsIContent.h
+++ b/dom/base/nsIContent.h
@@ -50,16 +50,18 @@ enum nsLinkState {
 /**
  * A node of content in a document's content model. This interface
  * is supported by all content objects.
  */
 class nsIContent : public nsINode {
 public:
   typedef mozilla::widget::IMEState IMEState;
 
+  void ConstructUbiNode(void* storage) override;
+
 #ifdef MOZILLA_INTERNAL_API
   // If you're using the external API, the only thing you can know about
   // nsIContent is that it exists with an IID
 
   explicit nsIContent(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
     : nsINode(aNodeInfo)
   {
     MOZ_ASSERT(mNodeInfo);
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -3037,16 +3037,18 @@ public:
   // only appear at the top of the DOM tree, we have a specialized measurement
   // function which returns multiple sizes.
   virtual void DocAddSizeOfExcludingThis(nsWindowSizes& aWindowSizes) const;
   // DocAddSizeOfIncludingThis doesn't need to be overridden by sub-classes
   // because nsIDocument inherits from nsINode;  see the comment above the
   // declaration of nsINode::SizeOfIncludingThis.
   virtual void DocAddSizeOfIncludingThis(nsWindowSizes& aWindowSizes) const;
 
+  void ConstructUbiNode(void* storage) override;
+
   bool MayHaveDOMMutationObservers()
   {
     return mMayHaveDOMMutationObservers;
   }
 
   void SetMayHaveDOMMutationObservers()
   {
     mMayHaveDOMMutationObservers = true;
--- a/dom/base/nsINode.h
+++ b/dom/base/nsINode.h
@@ -451,16 +451,22 @@ public:
    * This is defined inline in DocumentFragment.h.
    */
   inline mozilla::dom::DocumentFragment* AsDocumentFragment();
   inline const mozilla::dom::DocumentFragment* AsDocumentFragment() const;
 
   virtual JSObject* WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
 
   /**
+  * Hook for constructing JS::ubi::Concrete specializations for memory reporting.
+  * Specializations are defined in NodeUbiReporting.h.
+  */
+  virtual void ConstructUbiNode(void* storage) = 0;
+
+  /**
    * returns true if we are in priviliged code or
    * layout.css.getBoxQuads.enabled == true.
    */
   static bool HasBoxQuadsSupport(JSContext* aCx, JSObject* /* unused */);
 
 protected:
   /**
    * WrapNode is called from WrapObject to actually wrap this node, WrapObject
--- a/dom/fetch/FetchUtil.cpp
+++ b/dom/fetch/FetchUtil.cpp
@@ -596,17 +596,17 @@ FetchUtil::StreamResponseToJS(JSContext*
   }
 
   IgnoredErrorResult error;
   response->SetBodyUsed(aCx, error);
   if (NS_WARN_IF(error.Failed())) {
     return ThrowException(aCx, JSMSG_ERROR_CONSUMING_RESPONSE);
   }
 
-  nsIGlobalObject* global = xpc::NativeGlobal(aObj);
+  nsIGlobalObject* global = xpc::NativeGlobal(js::UncheckedUnwrap(aObj));
 
   if (!JSStreamConsumer::Start(body, aConsumer, global, aMaybeWorker)) {
     return ThrowException(aCx, JSMSG_OUT_OF_MEMORY);
   }
 
   return true;
 }
 
--- a/dom/html/nsBrowserElement.cpp
+++ b/dom/html/nsBrowserElement.cpp
@@ -14,16 +14,18 @@
 #include "mozilla/dom/ToJSValue.h"
 
 #include "nsComponentManagerUtils.h"
 #include "nsFrameLoader.h"
 #include "nsIMozBrowserFrame.h"
 #include "nsINode.h"
 #include "nsIPrincipal.h"
 
+#include "js/Wrapper.h"
+
 using namespace mozilla::dom;
 
 namespace mozilla {
 
 bool
 nsBrowserElement::IsBrowserElementOrThrow(ErrorResult& aRv)
 {
   if (mBrowserElementAPI) {
@@ -179,16 +181,17 @@ nsBrowserElement::Download(const nsAStri
                            const BrowserElementDownloadOptions& aOptions,
                            ErrorResult& aRv)
 {
   NS_ENSURE_TRUE(IsBrowserElementOrThrow(aRv), nullptr);
 
   RefPtr<DOMRequest> req;
   nsCOMPtr<nsIXPConnectWrappedJS> wrappedObj = do_QueryInterface(mBrowserElementAPI);
   MOZ_ASSERT(wrappedObj, "Failed to get wrapped JS from XPCOM component.");
+  MOZ_RELEASE_ASSERT(!js::IsWrapper(wrappedObj->GetJSObject()));
   AutoJSAPI jsapi;
   if (!jsapi.Init(wrappedObj->GetJSObject())) {
     aRv.Throw(NS_ERROR_UNEXPECTED);
     return nullptr;
   }
   JSContext* cx = jsapi.cx();
   JS::Rooted<JS::Value> options(cx);
   aRv.MightThrowJSException();
@@ -398,16 +401,17 @@ nsBrowserElement::ExecuteScript(const ns
                                 const BrowserElementExecuteScriptOptions& aOptions,
                                 ErrorResult& aRv)
 {
   NS_ENSURE_TRUE(IsBrowserElementOrThrow(aRv), nullptr);
 
   RefPtr<DOMRequest> req;
   nsCOMPtr<nsIXPConnectWrappedJS> wrappedObj = do_QueryInterface(mBrowserElementAPI);
   MOZ_ASSERT(wrappedObj, "Failed to get wrapped JS from XPCOM component.");
+  MOZ_RELEASE_ASSERT(!js::IsWrapper(wrappedObj->GetJSObject()));
   AutoJSAPI jsapi;
   if (!jsapi.Init(wrappedObj->GetJSObject())) {
     aRv.Throw(NS_ERROR_UNEXPECTED);
     return nullptr;
   }
   JSContext* cx = jsapi.cx();
   JS::Rooted<JS::Value> options(cx);
   aRv.MightThrowJSException();
--- a/dom/script/ScriptSettings.cpp
+++ b/dom/script/ScriptSettings.cpp
@@ -485,16 +485,17 @@ bool
 AutoJSAPI::Init(nsIGlobalObject* aGlobalObject)
 {
   return Init(aGlobalObject, danger::GetJSContext());
 }
 
 bool
 AutoJSAPI::Init(JSObject* aObject)
 {
+  MOZ_ASSERT(!js::IsCrossCompartmentWrapper(aObject));
   return Init(xpc::NativeGlobal(aObject));
 }
 
 bool
 AutoJSAPI::Init(nsPIDOMWindowInner* aWindow, JSContext* aCx)
 {
   return Init(nsGlobalWindowInner::Cast(aWindow), aCx);
 }
--- a/dom/script/ScriptSettings.h
+++ b/dom/script/ScriptSettings.h
@@ -223,17 +223,18 @@ public:
   // false and use of cx() will cause an assertion.
   //
   // If aGlobalObject represents a web-visible global, errors reported by this
   // AutoJSAPI as it comes off the stack will fire the relevant error events and
   // show up in the corresponding web console.
   MOZ_MUST_USE bool Init(nsIGlobalObject* aGlobalObject);
 
   // This is a helper that grabs the native global associated with aObject and
-  // invokes the above Init() with that.
+  // invokes the above Init() with that. aObject must not be a cross-compartment
+  // wrapper: CCWs are not associated with a single global.
   MOZ_MUST_USE bool Init(JSObject* aObject);
 
   // Unsurprisingly, this uses aCx and enters the compartment of aGlobalObject.
   // If aGlobalObject or its associated JS global are null then it returns
   // false and use of cx() will cause an assertion.
   // If aCx is null it will cause an assertion.
   //
   // If aGlobalObject represents a web-visible global, errors reported by this
--- a/dom/serviceworkers/ServiceWorkerScriptCache.cpp
+++ b/dom/serviceworkers/ServiceWorkerScriptCache.cpp
@@ -36,36 +36,31 @@ using mozilla::ipc::PrincipalInfo;
 
 namespace mozilla {
 namespace dom {
 
 namespace serviceWorkerScriptCache {
 
 namespace {
 
-// XXX A sandbox nsIGlobalObject does not preserve its reflector, so |aSandbox|
-// must be kept alive as long as the CacheStorage if you want to ensure that
-// the CacheStorage will continue to work. Failures will manifest as errors
-// like "JavaScript error: , line 0: TypeError: The expression cannot be
-// converted to return the specified type."
 already_AddRefed<CacheStorage>
-CreateCacheStorage(JSContext* aCx, nsIPrincipal* aPrincipal, ErrorResult& aRv,
-                   JS::MutableHandle<JSObject*> aSandbox)
+CreateCacheStorage(JSContext* aCx, nsIPrincipal* aPrincipal, ErrorResult& aRv)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aPrincipal);
 
   nsIXPConnect* xpc = nsContentUtils::XPConnect();
   MOZ_ASSERT(xpc, "This should never be null!");
-  aRv = xpc->CreateSandbox(aCx, aPrincipal, aSandbox.address());
+  JS::Rooted<JSObject*> sandbox(aCx);
+  aRv = xpc->CreateSandbox(aCx, aPrincipal, sandbox.address());
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
-  nsCOMPtr<nsIGlobalObject> sandboxGlobalObject = xpc::NativeGlobal(aSandbox);
+  nsCOMPtr<nsIGlobalObject> sandboxGlobalObject = xpc::NativeGlobal(sandbox);
   if (!sandboxGlobalObject) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   // We assume private browsing is not enabled here.  The ScriptLoader
   // explicitly fails for private browsing so there should never be
   // a service worker running in private browsing mode.  Therefore if
@@ -661,17 +656,16 @@ private:
 
     mPendingCount += 1;
     cachePromise->AppendNativeHandler(this);
     return NS_OK;
   }
 
   RefPtr<ServiceWorkerRegistrationInfo> mRegistration;
   RefPtr<CompareCallback> mCallback;
-  JS::PersistentRooted<JSObject*> mSandbox;
   RefPtr<CacheStorage> mCacheStorage;
 
   nsTArray<RefPtr<CompareNetwork>> mCNList;
 
   nsString mURL;
   RefPtr<nsIPrincipal> mPrincipal;
   RefPtr<nsILoadGroup> mLoadGroup;
 
@@ -1281,18 +1275,17 @@ CompareManager::Initialize(nsIPrincipal*
   mPrincipal = aPrincipal;
   mLoadGroup = aLoadGroup;
 
   // Always create a CacheStorage since we want to write the network entry to
   // the cache even if there isn't an existing one.
   AutoJSAPI jsapi;
   jsapi.Init();
   ErrorResult result;
-  mSandbox.init(jsapi.cx());
-  mCacheStorage = CreateCacheStorage(jsapi.cx(), aPrincipal, result, &mSandbox);
+  mCacheStorage = CreateCacheStorage(jsapi.cx(), aPrincipal, result);
   if (NS_WARN_IF(result.Failed())) {
     MOZ_ASSERT(!result.IsErrorWithMessage());
     return result.StealNSResult();
   }
 
   // If there is no existing cache, proceed to fetch the script directly.
   if (aCacheName.IsEmpty()) {
     mState = WaitingForScriptOrComparisonResult;
@@ -1424,18 +1417,17 @@ PurgeCache(nsIPrincipal* aPrincipal, con
 
   if (aCacheName.IsEmpty()) {
     return NS_OK;
   }
 
   AutoJSAPI jsapi;
   jsapi.Init();
   ErrorResult rv;
-  JS::Rooted<JSObject*> sandboxObject(jsapi.cx());
-  RefPtr<CacheStorage> cacheStorage = CreateCacheStorage(jsapi.cx(), aPrincipal, rv, &sandboxObject);
+  RefPtr<CacheStorage> cacheStorage = CreateCacheStorage(jsapi.cx(), aPrincipal, rv);
   if (NS_WARN_IF(rv.Failed())) {
     return rv.StealNSResult();
   }
 
   // We use the ServiceWorker scope as key for the cacheStorage.
   RefPtr<Promise> promise =
     cacheStorage->Delete(aCacheName, rv);
   if (NS_WARN_IF(rv.Failed())) {
--- a/dom/serviceworkers/test/test_serviceworker_interfaces.js
+++ b/dom/serviceworkers/test/test_serviceworker_interfaces.js
@@ -52,17 +52,16 @@ var ecmaGlobals =
     "Proxy",
     "RangeError",
     {name: "ReadableStream", optional: true},
     "ReferenceError",
     "Reflect",
     "RegExp",
     "Set",
     {name: "SharedArrayBuffer", disabled: true},
-    {name: "SIMD", nightly: true},
     "String",
     "Symbol",
     "SyntaxError",
     {name: "TypedObject", nightly: true},
     "TypeError",
     "Uint16Array",
     "Uint32Array",
     "Uint8Array",
--- a/dom/svg/SVGAnimationElement.cpp
+++ b/dom/svg/SVGAnimationElement.cpp
@@ -277,16 +277,20 @@ SVGAnimationElement::AfterSetAttr(int32_
 
   if (SVGTests::IsConditionalProcessingAttribute(aName)) {
     bool isDisabled = !SVGTests::PassesConditionalProcessingTests();
     if (mTimedElement.SetIsDisabled(isDisabled)) {
       AnimationNeedsResample();
     }
   }
 
+  if (!IsInComposedDoc()) {
+    return rv;
+  }
+
   if (!((aNamespaceID == kNameSpaceID_None ||
          aNamespaceID == kNameSpaceID_XLink) &&
         aName == nsGkAtoms::href)) {
     return rv;
   }
 
   if (!aValue) {
     if (aNamespaceID == kNameSpaceID_None) {
@@ -300,18 +304,17 @@ SVGAnimationElement::AfterSetAttr(int32_
       if (xlinkHref) {
         UpdateHrefTarget(xlinkHref->GetStringValue());
       }
     } else if (!HasAttr(kNameSpaceID_None, nsGkAtoms::href)) {
       mHrefTarget.Unlink();
       AnimationTargetChanged();
     } // else: we unset xlink:href, but we still have href attribute, so keep
       // mHrefTarget linking to href.
-  } else if (IsInComposedDoc() &&
-             !(aNamespaceID == kNameSpaceID_XLink &&
+  } else if (!(aNamespaceID == kNameSpaceID_XLink &&
                HasAttr(kNameSpaceID_None, nsGkAtoms::href))) {
     // Note: "href" takes priority over xlink:href. So if "xlink:href" is being
     // set here, we only let that update our target if "href" is *unset*.
     MOZ_ASSERT(aValue->Type() == nsAttrValue::eString,
                "Expected href attribute to be string type");
     UpdateHrefTarget(aValue->GetStringValue());
   } // else: we're not yet in a document -- we'll update the target on
     // next BindToTree call.
--- a/dom/tests/mochitest/general/test_interfaces.js
+++ b/dom/tests/mochitest/general/test_interfaces.js
@@ -73,17 +73,16 @@ var ecmaGlobals =
     {name: "Proxy", insecureContext: true},
     {name: "RangeError", insecureContext: true},
     {name: "ReadableStream", insecureContext: true, disabled: true},
     {name: "ReferenceError", insecureContext: true},
     {name: "Reflect", insecureContext: true},
     {name: "RegExp", insecureContext: true},
     {name: "Set", insecureContext: true},
     {name: "SharedArrayBuffer", insecureContext: true, disabled: true},
-    {name: "SIMD", insecureContext: true, nightly: true},
     {name: "String", insecureContext: true},
     {name: "Symbol", insecureContext: true},
     {name: "SyntaxError", insecureContext: true},
     {name: "TypedObject", insecureContext: true, nightly: true},
     {name: "TypeError", insecureContext: true},
     {name: "Uint16Array", insecureContext: true},
     {name: "Uint32Array", insecureContext: true},
     {name: "Uint8Array", insecureContext: true},
--- a/dom/workers/test/test_worker_interfaces.js
+++ b/dom/workers/test/test_worker_interfaces.js
@@ -58,17 +58,16 @@ var ecmaGlobals =
     {name: "Proxy", insecureContext: true},
     {name: "RangeError", insecureContext: true},
     {name: "ReadableStream", insecureContext: true, disabled: true},
     {name: "ReferenceError", insecureContext: true},
     {name: "Reflect", insecureContext: true},
     {name: "RegExp", insecureContext: true},
     {name: "Set", insecureContext: true},
     {name: "SharedArrayBuffer", insecureContext: true, disabled: true},
-    {name: "SIMD", insecureContext: true, nightly: true},
     {name: "String", insecureContext: true},
     {name: "Symbol", insecureContext: true},
     {name: "SyntaxError", insecureContext: true},
     {name: "TypedObject", insecureContext: true, nightly: true},
     {name: "TypeError", insecureContext: true},
     {name: "Uint16Array", insecureContext: true},
     {name: "Uint32Array", insecureContext: true},
     {name: "Uint8Array", insecureContext: true},
--- a/dom/xbl/nsXBLBinding.cpp
+++ b/dom/xbl/nsXBLBinding.cpp
@@ -887,17 +887,18 @@ GetOrCreateMapEntryForPrototype(JSContex
   // to content prototypes), and the other for class objects that live in the
   // XBL scope (prototyped to cross-compartment-wrapped content prototypes).
   const char* name = xpc::IsInContentXBLScope(proto) ? "__ContentClassObjectMap__"
                                                      : "__XBLClassObjectMap__";
 
   // Now, enter the XBL scope, since that's where we need to operate, and wrap
   // the proto accordingly. We hang the map off of the content XBL scope for
   // content, and the Window for chrome (whether add-ons are involved or not).
-  JS::Rooted<JSObject*> scope(cx, xpc::GetXBLScopeOrGlobal(cx, proto));
+  JS::Rooted<JSObject*> scope(cx,
+    xpc::GetXBLScopeOrGlobal(cx, JS::CurrentGlobalOrNull(cx)));
   NS_ENSURE_TRUE(scope, nullptr);
   MOZ_ASSERT(JS_IsGlobalObject(scope));
 
   JS::Rooted<JSObject*> wrappedProto(cx, proto);
   JSAutoRealm ar(cx, scope);
   if (!JS_WrapObject(cx, &wrappedProto)) {
     return nullptr;
   }
@@ -953,17 +954,20 @@ nsXBLBinding::DoInitJSClass(JSContext *c
   MOZ_ASSERT(obj);
 
   // Note that, now that NAC reflectors are created in the XBL scope, the
   // reflector is not necessarily same-compartment with the document. So we'll
   // end up creating a separate instance of the oddly-named XBL class object
   // and defining it as a property on the XBL scope's global. This works fine,
   // but we need to make sure never to assume that the the reflector and
   // prototype are same-compartment with the bound document.
-  JS::Rooted<JSObject*> global(cx, js::GetGlobalForObjectCrossCompartment(obj));
+  JS::Rooted<JSObject*> global(cx, JS::GetNonCCWObjectGlobal(obj));
+
+  // We must be in obj's realm.
+  MOZ_ASSERT(JS::CurrentGlobalOrNull(cx) == global);
 
   // We never store class objects in add-on scopes.
   JS::Rooted<JSObject*> xblScope(cx, xpc::GetXBLScopeOrGlobal(cx, global));
   NS_ENSURE_TRUE(xblScope, NS_ERROR_UNEXPECTED);
 
   JS::Rooted<JSObject*> parent_proto(cx);
   {
     JS::RootedObject wrapped(cx, obj);
@@ -1110,17 +1114,17 @@ nsXBLBinding::LookupMember(JSContext* aC
   // into content. So for NAC reflectors that live in the XBL scope, we should
   // never get here. But on the off-chance that someone adds new callsites to
   // LookupMember, we do a release-mode assertion as belt-and-braces.
   // We do a release-mode assertion here to be extra safe.
   //
   // This code is only called for content XBL, so we don't have to worry about
   // add-on scopes here.
   JS::Rooted<JSObject*> boundScope(aCx,
-    js::GetGlobalForObjectCrossCompartment(mBoundElement->GetWrapper()));
+    JS::GetNonCCWObjectGlobal(mBoundElement->GetWrapper()));
   MOZ_RELEASE_ASSERT(!xpc::IsInContentXBLScope(boundScope));
   JS::Rooted<JSObject*> xblScope(aCx, xpc::GetXBLScope(aCx, boundScope));
   NS_ENSURE_TRUE(xblScope, false);
   MOZ_ASSERT(boundScope != xblScope);
 
   // Enter the xbl scope and invoke the internal version.
   {
     JSAutoRealm ar(aCx, xblScope);
--- a/dom/xbl/nsXBLProtoImpl.cpp
+++ b/dom/xbl/nsXBLProtoImpl.cpp
@@ -17,17 +17,16 @@
 #include "nsIURI.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/dom/XULElementBinding.h"
 #include "xpcpublic.h"
 #include "js/CharacterEncoding.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
-using js::GetGlobalForObjectCrossCompartment;
 using js::AssertSameCompartment;
 
 nsresult
 nsXBLProtoImpl::InstallImplementation(nsXBLPrototypeBinding* aPrototypeBinding,
                                       nsXBLBinding* aBinding)
 {
   // This function is called to install a concrete implementation on a bound element using
   // this prototype implementation as a guide.  The prototype implementation is compiled lazily,
@@ -77,17 +76,17 @@ nsXBLProtoImpl::InstallImplementation(ns
   // they'll be available for Xray lookups, among other things), and then copy
   // the properties to the content-side prototype as needed. We don't need to
   // bother about the field accessors here, since we don't use/support those
   // for in-content bindings.
 
   // First, start by entering the realm of the XBL scope. This may or may
   // not be the same realm as globalObject.
   JS::Rooted<JSObject*> globalObject(cx,
-    GetGlobalForObjectCrossCompartment(targetClassObject));
+    JS::GetNonCCWObjectGlobal(targetClassObject));
   JS::Rooted<JSObject*> scopeObject(cx, xpc::GetXBLScopeOrGlobal(cx, globalObject));
   NS_ENSURE_TRUE(scopeObject, NS_ERROR_OUT_OF_MEMORY);
   MOZ_ASSERT(JS_IsGlobalObject(scopeObject));
   JSAutoRealm ar(cx, scopeObject);
 
   // Determine the appropriate property holder.
   //
   // Note: If |targetIsNew| is false, we'll early-return above. However, that only
@@ -213,16 +212,20 @@ nsXBLProtoImpl::InitTargetObjects(nsXBLP
 
   rv = nsContentUtils::WrapNative(cx, aBoundElement, &v,
                                   /* aAllowWrapping = */ false);
   NS_ENSURE_SUCCESS(rv, rv);
 
   JS::Rooted<JSObject*> value(cx, &v.toObject());
   JSAutoRealm ar2(cx, value);
 
+  // We passed aAllowWrapping = false to nsContentUtils::WrapNative so we
+  // should not have a wrapper.
+  MOZ_ASSERT(!js::IsWrapper(value));
+
   // All of the above code was just obtaining the bound element's script object and its immediate
   // concrete base class.  We need to alter the object so that our concrete class is interposed
   // between the object and its base class.  We become the new base class of the object, and the
   // object's old base class becomes the new class' base class.
   rv = aBinding->InitClass(mClassName, cx, value, aTargetClassObject, aTargetIsNew);
   if (NS_FAILED(rv)) {
     return rv;
   }
new file mode 100644
--- /dev/null
+++ b/gfx/qcms/fuzztest/qcms_fuzzer.dict
@@ -0,0 +1,26 @@
+# v2
+0x41324230="A2B0"
+0x42324130="B2A0"
+0x47524159="GRAY"
+0x4C616220="Lab "
+0x52474220="RGB "
+0x58595a20="XYZ "
+0x62545243="bTRC"
+0x6258595a="bXYZ"
+0x63686164="chad"
+0x63757276="curv"
+0x67545243="gTRC"
+0x6758595a="gXYZ"
+0x6D667431="mft1"
+0x6D667432="mft2"
+0x6b545243="kTRC"
+0x6d6e7472="mntr"
+0x72545243="rTRC"
+0x7258595a="rXYZ"
+0x73636e72="scnr"
+0x73663332="sf32"
+
+# v4
+0x6D414220="mAB "
+0x6D424120="mBA "
+0x70617261="para"
--- a/gfx/skia/skia/src/ports/SkScalerContext_win_dw.cpp
+++ b/gfx/skia/skia/src/ports/SkScalerContext_win_dw.cpp
@@ -300,28 +300,24 @@ SkScalerContext_DW::SkScalerContext_DW(s
     } else if ((get_gasp_range(typeface, SkScalarRoundToInt(gdiTextSize), &range) &&
                 range.fVersion >= 1) ||
                realTextSize > SkIntToScalar(20) || !is_hinted(typeface)) {
         fTextSizeRender = realTextSize;
         fTextureType = DWRITE_TEXTURE_CLEARTYPE_3x1;
         fTextSizeMeasure = realTextSize;
         fMeasuringMode = DWRITE_MEASURING_MODE_NATURAL;
 
-        IDWriteFactory* factory = sk_get_dwrite_factory();
-        if (factory != nullptr) {
-            HRVM(factory->CreateRenderingParams(&fDefaultRenderingParams),
-            "Could not create default rendering params");
-        }
-
+        IDWriteRenderingParams* params = sk_get_dwrite_default_rendering_params();
         DWriteFontTypeface* typeface = static_cast<DWriteFontTypeface*>(getTypeface());
-        if (!SUCCEEDED(typeface->fDWriteFontFace->GetRecommendedRenderingMode(
+        if (params &&
+            !SUCCEEDED(typeface->fDWriteFontFace->GetRecommendedRenderingMode(
                 fTextSizeRender,
                 1.0f,
                 fMeasuringMode,
-                fDefaultRenderingParams.get(),
+                params,
                 &fRenderingMode))) {
             fRenderingMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC;
         }
 
         // We don't support outline mode right now.
         if (fRenderingMode == DWRITE_RENDERING_MODE_OUTLINE) {
             fRenderingMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC;
         }
--- a/gfx/skia/skia/src/ports/SkScalerContext_win_dw.h
+++ b/gfx/skia/skia/src/ports/SkScalerContext_win_dw.h
@@ -65,13 +65,12 @@ private:
     /** The text size to measure with. */
     SkScalar fTextSizeMeasure;
     int fGlyphCount;
     DWRITE_RENDERING_MODE fRenderingMode;
     DWRITE_TEXTURE_TYPE fTextureType;
     DWRITE_MEASURING_MODE fMeasuringMode;
     DWRITE_TEXT_ANTIALIAS_MODE fAntiAliasMode;
     DWRITE_GRID_FIT_MODE fGridFitMode;
-    SkTScopedComPtr<IDWriteRenderingParams> fDefaultRenderingParams;
     bool fIsColorFont;
 };
 
 #endif
--- a/gfx/skia/skia/src/utils/win/SkDWrite.cpp
+++ b/gfx/skia/skia/src/utils/win/SkDWrite.cpp
@@ -44,16 +44,40 @@ static void create_dwrite_factory(IDWrit
 
 
 IDWriteFactory* sk_get_dwrite_factory() {
     static SkOnce once;
     once(create_dwrite_factory, &gDWriteFactory);
     return gDWriteFactory;
 }
 
+static IDWriteRenderingParams* gDWriteRenderingParams = nullptr;
+
+static void release_dwrite_rendering_params() {
+    if (gDWriteRenderingParams) {
+        gDWriteRenderingParams->Release();
+    }
+}
+
+static void create_dwrite_rendering_params(IDWriteRenderingParams** params) {
+    IDWriteFactory* factory = sk_get_dwrite_factory();
+    if (!factory) {
+        return;
+    }
+    HRVM(factory->CreateRenderingParams(params),
+        "Could not create DWrite default rendering params");
+    atexit(release_dwrite_rendering_params);
+}
+
+IDWriteRenderingParams* sk_get_dwrite_default_rendering_params() {
+    static SkOnce once;
+    once(create_dwrite_rendering_params, &gDWriteRenderingParams);
+    return gDWriteRenderingParams;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // String conversion
 
 /** Converts a utf8 string to a WCHAR string. */
 HRESULT sk_cstring_to_wchar(const char* skname, SkSMallocWCHAR* name) {
     int wlen = MultiByteToWideChar(CP_UTF8, 0, skname, -1, nullptr, 0);
     if (0 == wlen) {
         HRM(HRESULT_FROM_WIN32(GetLastError()),
--- a/gfx/skia/skia/src/utils/win/SkDWrite.h
+++ b/gfx/skia/skia/src/utils/win/SkDWrite.h
@@ -15,16 +15,17 @@
 #include <winsdkver.h>
 
 class SkString;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Factory
 
 IDWriteFactory* sk_get_dwrite_factory();
+IDWriteRenderingParams* sk_get_dwrite_default_rendering_params();
 
 ////////////////////////////////////////////////////////////////////////////////
 // String conversion
 
 /** Prefer to use this type to prevent template proliferation. */
 typedef SkAutoSTMalloc<16, WCHAR> SkSMallocWCHAR;
 
 /** Converts a utf8 string to a WCHAR string. */
--- a/gfx/src/moz.build
+++ b/gfx/src/moz.build
@@ -30,17 +30,16 @@ EXPORTS += [
     'nsITheme.h',
     'nsMargin.h',
     'nsPoint.h',
     'nsRect.h',
     'nsRectAbsolute.h',
     'nsRegion.h',
     'nsRegionFwd.h',
     'nsSize.h',
-    'nsThemeConstants.h',
     'nsTransform2D.h',
     'RegionBuilder.h',
     'X11UndefineNone.h'
 ]
 
 EXPORTS.mozilla += [
     'AppUnits.h',
     'ArrayView.h',
--- a/gfx/src/nsITheme.h
+++ b/gfx/src/nsITheme.h
@@ -20,16 +20,17 @@ class nsAttrValue;
 class nsPresContext;
 class nsDeviceContext;
 class nsIFrame;
 class nsAtom;
 class nsIWidget;
 
 namespace mozilla {
 class ComputedStyle;
+enum class StyleAppearance : uint8_t;
 namespace layers {
 class StackingContextHelper;
 class WebRenderLayerManager;
 }
 namespace wr {
 class DisplayListBuilder;
 class IpcResourceUpdateQueue;
 }
@@ -53,138 +54,138 @@ class IpcResourceUpdateQueue;
  *
  * All the methods on nsITheme take a rendering context or device
  * context, a frame (the rendering object), and a widget type (one of
  * the constants in nsThemeConstants.h).
  */
 class nsITheme: public nsISupports {
 protected:
   using LayoutDeviceIntMargin = mozilla::LayoutDeviceIntMargin;
+  using WidgetType = mozilla::StyleAppearance;
 
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ITHEME_IID)
 
   /**
    * Draw the actual theme background.
    * @param aContext the context to draw into
    * @param aFrame the frame for the widget that we're drawing
    * @param aWidgetType the -moz-appearance value to draw
    * @param aRect the rectangle defining the area occupied by the widget
    * @param aDirtyRect the rectangle that needs to be drawn
    */
   NS_IMETHOD DrawWidgetBackground(gfxContext* aContext,
                                   nsIFrame* aFrame,
-                                  uint8_t aWidgetType,
+                                  WidgetType aWidgetType,
                                   const nsRect& aRect,
                                   const nsRect& aDirtyRect) = 0;
 
   /**
    * Get the used color of the given widget when it's specified as auto.
    * It's currently only used for scrollbar-*-color properties.
    */
   virtual nscolor GetWidgetAutoColor(mozilla::ComputedStyle* aStyle,
-                                     uint8_t aWidgetType)
+                                     WidgetType aWidgetType)
   { return NS_RGB(0, 0, 0); }
 
   /**
    * Create WebRender commands for the theme background.
    * @return true if the theme knows how to create WebRender commands for the
    *         given widget type, false if DrawWidgetBackground need sto be called
    *         instead.
    */
   virtual bool CreateWebRenderCommandsForWidget(mozilla::wr::DisplayListBuilder& aBuilder,
                                                 mozilla::wr::IpcResourceUpdateQueue& aResources,
                                                 const mozilla::layers::StackingContextHelper& aSc,
                                                 mozilla::layers::WebRenderLayerManager* aManager,
                                                 nsIFrame* aFrame,
-                                                uint8_t aWidgetType,
+                                                WidgetType aWidgetType,
                                                 const nsRect& aRect) { return false; }
 
   /**
    * Return the border for the widget, in device pixels.
    */
   virtual MOZ_MUST_USE LayoutDeviceIntMargin GetWidgetBorder(nsDeviceContext* aContext,
                                                              nsIFrame* aFrame,
-                                                             uint8_t aWidgetType) = 0;
+                                                             WidgetType aWidgetType) = 0;
 
   /**
    * This method can return false to indicate that the CSS padding
    * value should be used.  Otherwise, it will fill in aResult with the
    * computed padding, in pixels, and return true.
    *
    * XXXldb This ought to be required to return true for non-containers
    * so that we don't let specified padding that has no effect change
    * the computed padding and potentially the size.
    */
   virtual bool GetWidgetPadding(nsDeviceContext* aContext,
-                                  nsIFrame* aFrame,
-                                  uint8_t aWidgetType,
-                                  LayoutDeviceIntMargin* aResult) = 0;
+                                nsIFrame* aFrame,
+                                WidgetType aWidgetType,
+                                LayoutDeviceIntMargin* aResult) = 0;
 
   /**
    * On entry, *aResult is positioned at 0,0 and sized to the new size
    * of aFrame (aFrame->GetSize() may be stale and should not be used).
    * This method can return false to indicate that no special
    * overflow area is required by the native widget. Otherwise it will
    * fill in aResult with the desired overflow area, in appunits, relative
    * to the frame origin, and return true.
    *
    * This overflow area is used to determine what area needs to be
    * repainted when the widget changes.  However, it does not affect the
    * widget's size or what area is reachable by scrollbars.  (In other
    * words, in layout terms, it affects visual overflow but not
    * scrollable overflow.)
    */
   virtual bool GetWidgetOverflow(nsDeviceContext* aContext,
-                                   nsIFrame* aFrame,
-                                   uint8_t aWidgetType,
-                                   /*INOUT*/ nsRect* aOverflowRect)
+                                 nsIFrame* aFrame,
+                                 WidgetType aWidgetType,
+                                 /*INOUT*/ nsRect* aOverflowRect)
   { return false; }
 
   /**
    * Get the minimum border-box size of a widget, in *pixels* (in
    * |aResult|).  If |aIsOverridable| is set to true, this size is a
    * minimum size; if false, this size is the only valid size for the
    * widget.
    */
   NS_IMETHOD GetMinimumWidgetSize(nsPresContext* aPresContext,
                                   nsIFrame* aFrame,
-                                  uint8_t aWidgetType,
+                                  WidgetType aWidgetType,
                                   mozilla::LayoutDeviceIntSize* aResult,
                                   bool* aIsOverridable)=0;
 
 
   enum Transparency {
     eOpaque = 0,
     eTransparent,
     eUnknownTransparency
   };
 
   /**
    * Returns what we know about the transparency of the widget.
    */
-  virtual Transparency GetWidgetTransparency(nsIFrame* aFrame, uint8_t aWidgetType)
+  virtual Transparency GetWidgetTransparency(nsIFrame* aFrame, WidgetType aWidgetType)
   { return eUnknownTransparency; }
 
   /**
    * Sets |*aShouldRepaint| to indicate whether an attribute or content state
    * change should trigger a repaint.  Call with null |aAttribute| (and
    * null |aOldValue|) for content state changes.
    */
-  NS_IMETHOD WidgetStateChanged(nsIFrame* aFrame, uint8_t aWidgetType, 
+  NS_IMETHOD WidgetStateChanged(nsIFrame* aFrame, WidgetType aWidgetType,
                                 nsAtom* aAttribute, bool* aShouldRepaint,
                                 const nsAttrValue* aOldValue)=0;
 
   NS_IMETHOD ThemeChanged()=0;
 
-  virtual bool WidgetAppearanceDependsOnWindowFocus(uint8_t aWidgetType)
+  virtual bool WidgetAppearanceDependsOnWindowFocus(WidgetType aWidgetType)
   { return false; }
 
-  virtual bool NeedToClearBackgroundBehindWidget(nsIFrame* aFrame,
-                                                 uint8_t aWidgetType)
+  virtual bool NeedToClearBackgroundBehindWidget(nsIFrame* aFrame, WidgetType aWidgetType)
   { return false; }
 
   /**
    * ThemeGeometryType values are used for describing themed nsIFrames in
    * calls to nsIWidget::UpdateThemeGeometries. We don't simply pass the
    * -moz-appearance value ("widget type") of the frame because the widget may
    * want to treat different frames with the same -moz-appearance differently
    * based on other properties of the frame. So we give the theme a first look
@@ -201,37 +202,37 @@ public:
 
   /**
    * Returns the theme geometry type that should be used in the ThemeGeometry
    * array that's passed to the widget using nsIWidget::UpdateThemeGeometries.
    * A return value of eThemeGeometryTypeUnknown means that this frame will
    * not be included in the ThemeGeometry array.
    */
   virtual ThemeGeometryType ThemeGeometryTypeForWidget(nsIFrame* aFrame,
-                                                       uint8_t aWidgetType)
+                                                       WidgetType aWidgetType)
   { return eThemeGeometryTypeUnknown; }
 
   /**
    * Can the nsITheme implementation handle this widget?
    */
   virtual bool ThemeSupportsWidget(nsPresContext* aPresContext,
-                                     nsIFrame* aFrame,
-                                     uint8_t aWidgetType)=0;
+                                   nsIFrame* aFrame,
+                                   WidgetType aWidgetType) = 0;
 
-  virtual bool WidgetIsContainer(uint8_t aWidgetType)=0;
+  virtual bool WidgetIsContainer(WidgetType aWidgetType) = 0;
 
   /**
    * Does the nsITheme implementation draw its own focus ring for this widget?
    */
-  virtual bool ThemeDrawsFocusForWidget(uint8_t aWidgetType)=0;
+  virtual bool ThemeDrawsFocusForWidget(WidgetType aWidgetType) = 0;
   
   /**
     * Should we insert a dropmarker inside of combobox button?
    */
-  virtual bool ThemeNeedsComboboxDropmarker()=0;
+  virtual bool ThemeNeedsComboboxDropmarker() = 0;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsITheme, NS_ITHEME_IID)
 
 // Creator function
 extern nsresult NS_NewNativeTheme(nsISupports *aOuter, REFNSIID aIID, void **aResult);
 
 #endif
deleted file mode 100644
--- a/gfx/src/nsThemeConstants.h
+++ /dev/null
@@ -1,316 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef nsThemeConstants_h_
-#define nsThemeConstants_h_
-
-enum ThemeWidgetType : uint8_t {
-
-  // No appearance at all.
-  NS_THEME_NONE,
-
-  // A typical dialog button.
-  NS_THEME_BUTTON,
-
-  // A radio element within a radio group.
-  NS_THEME_RADIO,
-
-  // A checkbox element.
-  NS_THEME_CHECKBOX,
-
-  // A rectangular button that contains complex content
-  // like images (e.g. HTML <button> elements)
-  NS_THEME_BUTTON_BEVEL,
-
-  // A themed focus outline (for outline:auto)
-  NS_THEME_FOCUS_OUTLINE,
-
-  // The toolbox that contains the toolbars.
-  NS_THEME_TOOLBOX,
-
-  // A toolbar in an application window.
-  NS_THEME_TOOLBAR,
-
-  // A single toolbar button (with no associated dropdown)
-  NS_THEME_TOOLBARBUTTON,
-
-  // A dual toolbar button (e.g., a Back button with a dropdown)
-  NS_THEME_DUALBUTTON,
-
-  // The dropdown portion of a toolbar button
-  NS_THEME_TOOLBARBUTTON_DROPDOWN,
-
-  // Various arrows that go in buttons
-  NS_THEME_BUTTON_ARROW_UP,
-  NS_THEME_BUTTON_ARROW_DOWN,
-  NS_THEME_BUTTON_ARROW_NEXT,
-  NS_THEME_BUTTON_ARROW_PREVIOUS,
-
-  // A separator.  Can be horizontal or vertical.
-  NS_THEME_SEPARATOR,
-
-  // The gripper for a toolbar.
-  NS_THEME_TOOLBARGRIPPER,
-
-  // A splitter.  Can be horizontal or vertical.
-  NS_THEME_SPLITTER,
-
-  // A status bar in a main application window.
-  NS_THEME_STATUSBAR,
-
-  // A single pane of a status bar.
-  NS_THEME_STATUSBARPANEL,
-
-  // The resizer background area in a status bar
-  // for the resizer widget in the corner of a window.
-  NS_THEME_RESIZERPANEL,
-
-  // The resizer itself.
-  NS_THEME_RESIZER,
-
-  // List boxes
-  NS_THEME_LISTBOX,
-
-  // A listbox item
-  NS_THEME_LISTITEM,
-
-  // A tree widget
-  NS_THEME_TREEVIEW,
-
-  // A tree item
-  NS_THEME_TREEITEM,
-
-  // A tree widget twisty
-  NS_THEME_TREETWISTY,
-
-  // A tree widget branch line
-  NS_THEME_TREELINE,
-
-  // A listbox or tree widget header
-  NS_THEME_TREEHEADER,
-
-  // An individual header cell
-  NS_THEME_TREEHEADERCELL,
-
-  // The sort arrow for a header.
-  NS_THEME_TREEHEADERSORTARROW,
-
-  // Open tree widget twisty
-  NS_THEME_TREETWISTYOPEN,
-
-  // A horizontal progress bar.
-  NS_THEME_PROGRESSBAR,
-
-  // The progress bar's progress indicator
-  NS_THEME_PROGRESSCHUNK,
-
-  // A vertical progress bar.
-  NS_THEME_PROGRESSBAR_VERTICAL,
-
-  // A vertical progress chunk
-  NS_THEME_PROGRESSCHUNK_VERTICAL,
-
-  // A horizontal meter bar.
-  NS_THEME_METERBAR,
-
-  // The meter bar's meter indicator
-  NS_THEME_METERCHUNK,
-
-  // A single tab in a tab widget.
-  NS_THEME_TAB,
-
-  // A single pane (inside the tabpanels container)
-  NS_THEME_TABPANEL,
-
-  // The tab panels container.
-  NS_THEME_TABPANELS,
-
-  // The tabs scroll arrows (left/right)
-  NS_THEME_TAB_SCROLL_ARROW_BACK,
-  NS_THEME_TAB_SCROLL_ARROW_FORWARD,
-
-  // A tooltip
-  NS_THEME_TOOLTIP,
-
-  // A inner-spin control
-  NS_THEME_INNER_SPIN_BUTTON,
-
-  // A spin control (up/down control for time/date pickers)
-  NS_THEME_SPINNER,
-
-  // The up button of a spin control
-  NS_THEME_SPINNER_UPBUTTON,
-
-  // The down button of a spin control
-  NS_THEME_SPINNER_DOWNBUTTON,
-
-  // The textfield of a spin control
-  NS_THEME_SPINNER_TEXTFIELD,
-
-  // For HTML's <input type=number>
-  NS_THEME_NUMBER_INPUT,
-
-  // A scrollbar.
-  NS_THEME_SCROLLBAR,
-
-  // A small scrollbar.
-  NS_THEME_SCROLLBAR_SMALL,
-
-  // The scrollbar slider
-  NS_THEME_SCROLLBAR_HORIZONTAL,
-  NS_THEME_SCROLLBAR_VERTICAL,
-
-  // A scrollbar button (up/down/left/right)
-  NS_THEME_SCROLLBARBUTTON_UP,
-  NS_THEME_SCROLLBARBUTTON_DOWN,
-  NS_THEME_SCROLLBARBUTTON_LEFT,
-  NS_THEME_SCROLLBARBUTTON_RIGHT,
-
-  // The scrollbar track
-  NS_THEME_SCROLLBARTRACK_HORIZONTAL,
-  NS_THEME_SCROLLBARTRACK_VERTICAL,
-
-  // The scrollbar thumb
-  NS_THEME_SCROLLBARTHUMB_HORIZONTAL,
-  NS_THEME_SCROLLBARTHUMB_VERTICAL,
-
-  // A non-disappearing scrollbar.
-  NS_THEME_SCROLLBAR_NON_DISAPPEARING,
-
-  // The scroll corner
-  NS_THEME_SCROLLCORNER,
-
-  // A textfield or text area
-  NS_THEME_TEXTFIELD,
-
-  // The caret of a text area
-  NS_THEME_CARET,
-
-  // A multiline text field
-  NS_THEME_TEXTFIELD_MULTILINE,
-
-  // A searchfield
-  NS_THEME_SEARCHFIELD,
-
-  // A dropdown list.
-  NS_THEME_MENULIST,
-
-  // The dropdown button(s) that open up a dropdown list.
-  NS_THEME_MENULIST_BUTTON,
-
-  // The text part of a dropdown list, to left of button
-  NS_THEME_MENULIST_TEXT,
-
-  // An editable textfield with a dropdown list (a combobox)
-  NS_THEME_MENULIST_TEXTFIELD,
-
-  // A slider
-  NS_THEME_SCALE_HORIZONTAL,
-  NS_THEME_SCALE_VERTICAL,
-
-  // A slider's thumb
-  NS_THEME_SCALETHUMB_HORIZONTAL,
-  NS_THEME_SCALETHUMB_VERTICAL,
-
-  // If the platform supports it, the left/right chunks
-  // of the slider thumb
-  NS_THEME_SCALETHUMBSTART,
-  NS_THEME_SCALETHUMBEND,
-
-  // The ticks for a slider.
-  NS_THEME_SCALETHUMBTICK,
-
-  // nsRangeFrame and its subparts
-  NS_THEME_RANGE,
-  NS_THEME_RANGE_THUMB,
-
-  // A groupbox
-  NS_THEME_GROUPBOX,
-
-  // A generic container that always repaints on state
-  // changes.  This is a hack to make checkboxes and
-  // radio buttons work.
-  NS_THEME_CHECKBOX_CONTAINER,
-  NS_THEME_RADIO_CONTAINER,
-
-  // The label part of a checkbox or radio button, used for painting
-  // a focus outline.
-  NS_THEME_CHECKBOX_LABEL,
-  NS_THEME_RADIO_LABEL,
-
-  // The focus outline box inside of a button
-  NS_THEME_BUTTON_FOCUS,
-
-  // Window and dialog backgrounds
-  NS_THEME_WINDOW,
-  NS_THEME_DIALOG,
-
-  // Menu Bar background
-  NS_THEME_MENUBAR,
-  // Menu Popup background
-  NS_THEME_MENUPOPUP,
-  // <menu> and <menuitem> appearances
-  NS_THEME_MENUITEM,
-  NS_THEME_CHECKMENUITEM,
-  NS_THEME_RADIOMENUITEM,
-
-  // menu checkbox/radio appearances
-  NS_THEME_MENUCHECKBOX,
-  NS_THEME_MENURADIO,
-  NS_THEME_MENUSEPARATOR,
-  NS_THEME_MENUARROW,
-  // An image in the menu gutter, like in bookmarks or history
-  NS_THEME_MENUIMAGE,
-  // For text on non-iconic menuitems only
-  NS_THEME_MENUITEMTEXT,
-
-  // Vista Rebars
-  NS_THEME_WIN_COMMUNICATIONS_TOOLBOX,
-  NS_THEME_WIN_MEDIA_TOOLBOX,
-  NS_THEME_WIN_BROWSERTABBAR_TOOLBOX,
-
-  // Titlebar elements on the Mac
-  NS_THEME_MAC_FULLSCREEN_BUTTON,
-
-  // Mac help button
-  NS_THEME_MAC_HELP_BUTTON,
-
-  // Vista glass
-  NS_THEME_WIN_BORDERLESS_GLASS,
-  NS_THEME_WIN_GLASS,
-
-  // Windows themed window frame elements
-  NS_THEME_WINDOW_TITLEBAR,
-  NS_THEME_WINDOW_TITLEBAR_MAXIMIZED,
-  NS_THEME_WINDOW_FRAME_LEFT,
-  NS_THEME_WINDOW_FRAME_RIGHT,
-  NS_THEME_WINDOW_FRAME_BOTTOM,
-  NS_THEME_WINDOW_BUTTON_CLOSE,
-  NS_THEME_WINDOW_BUTTON_MINIMIZE,
-  NS_THEME_WINDOW_BUTTON_MAXIMIZE,
-  NS_THEME_WINDOW_BUTTON_RESTORE,
-  NS_THEME_WINDOW_BUTTON_BOX,
-  NS_THEME_WINDOW_BUTTON_BOX_MAXIMIZED,
-
-  // moz-apperance style used in setting proper glass margins
-  NS_THEME_WIN_EXCLUDE_GLASS,
-
-  NS_THEME_MAC_VIBRANCY_LIGHT,
-  NS_THEME_MAC_VIBRANCY_DARK,
-  NS_THEME_MAC_VIBRANT_TITLEBAR_LIGHT,
-  NS_THEME_MAC_VIBRANT_TITLEBAR_DARK,
-  NS_THEME_MAC_DISCLOSURE_BUTTON_OPEN,
-  NS_THEME_MAC_DISCLOSURE_BUTTON_CLOSED,
-
-  NS_THEME_GTK_INFO_BAR,
-  NS_THEME_MAC_SOURCE_LIST,
-  NS_THEME_MAC_SOURCE_LIST_SELECTION,
-  NS_THEME_MAC_ACTIVE_SOURCE_LIST_SELECTION,
-
-  ThemeWidgetType_COUNT
-};
-
-#endif // nsThemeConstants_h_
--- a/js/public/ProtoKey.h
+++ b/js/public/ProtoKey.h
@@ -43,22 +43,16 @@
 #endif
 
 #ifdef ENABLE_BINARYDATA
 #define IF_BDATA(real,imaginary) real
 #else
 #define IF_BDATA(real,imaginary) imaginary
 #endif
 
-#ifdef ENABLE_SIMD
-# define IF_SIMD(real,imaginary) real
-#else
-# define IF_SIMD(real,imaginary) imaginary
-#endif
-
 #ifdef ENABLE_SHARED_ARRAY_BUFFER
 #define IF_SAB(real,imaginary) real
 #else
 #define IF_SAB(real,imaginary) imaginary
 #endif
 
 #define JS_FOR_PROTOTYPES(real,imaginary) \
     imaginary(Null,             InitNullClass,          dummy) \
@@ -101,17 +95,16 @@ IF_BIGINT(real,imaginary)(BigInt, InitVi
     real(Map,                   InitViaClassSpec,       OCLASP(Map)) \
     real(Set,                   InitViaClassSpec,       OCLASP(Set)) \
     real(DataView,              InitViaClassSpec,       OCLASP(DataView)) \
     real(Symbol,                InitSymbolClass,        OCLASP(Symbol)) \
 IF_SAB(real,imaginary)(SharedArrayBuffer,       InitViaClassSpec, OCLASP(SharedArrayBuffer)) \
 IF_INTL(real,imaginary) (Intl,                  InitIntlClass,          CLASP(Intl)) \
 IF_BDATA(real,imaginary)(TypedObject,           InitTypedObjectModuleObject,   OCLASP(TypedObjectModule)) \
     real(Reflect,               InitReflect,            nullptr) \
-IF_SIMD(real,imaginary)(SIMD,                   InitSimdClass, OCLASP(Simd)) \
     real(WeakSet,               InitWeakSetClass,       OCLASP(WeakSet)) \
     real(TypedArray,            InitViaClassSpec,       &js::TypedArrayObject::sharedTypedArrayPrototypeClass) \
 IF_SAB(real,imaginary)(Atomics, InitAtomicsClass, OCLASP(Atomics)) \
     real(SavedFrame,            InitViaClassSpec,       &js::SavedFrame::class_) \
     real(Promise,               InitViaClassSpec,       OCLASP(Promise)) \
     real(ReadableStream,        InitViaClassSpec,       &js::ReadableStream::class_) \
     real(ReadableStreamDefaultReader,           InitViaClassSpec, &js::ReadableStreamDefaultReader::class_) \
     real(ReadableStreamBYOBReader,              InitViaClassSpec, &js::ReadableStreamBYOBReader::class_) \
--- a/js/public/SliceBudget.h
+++ b/js/public/SliceBudget.h
@@ -32,23 +32,17 @@ struct JS_PUBLIC_API(WorkBudget)
 /*
  * This class records how much work has been done in a given collection slice,
  * so that we can return before pausing for too long. Some slices are allowed
  * to run for unlimited time, and others are bounded. To reduce the number of
  * gettimeofday calls, we only check the time every 1000 operations.
  */
 class JS_PUBLIC_API(SliceBudget)
 {
-    const mozilla::TimeStamp &UnlimitedDeadline() const {
-        mozilla::recordreplay::AutoPassThroughThreadEvents pt;
-        static const mozilla::TimeStamp unlimitedDeadline =
-            mozilla::TimeStamp::Now() + mozilla::TimeDuration::Forever();
-        return unlimitedDeadline;
-    }
-
+    static mozilla::TimeStamp unlimitedDeadline;
     static const intptr_t unlimitedStartCounter = INTPTR_MAX;
 
     bool checkOverBudget();
 
     SliceBudget();
 
   public:
     // Memory of the originally requested budget. If isUnlimited, neither of
@@ -70,32 +64,35 @@ class JS_PUBLIC_API(SliceBudget)
 
     /* Instantiate as SliceBudget(TimeBudget(n)). */
     explicit SliceBudget(TimeBudget time);
 
     /* Instantiate as SliceBudget(WorkBudget(n)). */
     explicit SliceBudget(WorkBudget work);
 
     void makeUnlimited() {
-        deadline = UnlimitedDeadline();
+        MOZ_ASSERT(unlimitedDeadline);
+        deadline = unlimitedDeadline;
         counter = unlimitedStartCounter;
     }
 
     void step(intptr_t amt = 1) {
         counter -= amt;
     }
 
     bool isOverBudget() {
         if (counter > 0)
             return false;
         return checkOverBudget();
     }
 
     bool isWorkBudget() const { return deadline.IsNull(); }
     bool isTimeBudget() const { return !deadline.IsNull() && !isUnlimited(); }
-    bool isUnlimited() const { return deadline == UnlimitedDeadline(); }
+    bool isUnlimited() const { return deadline == unlimitedDeadline; }
 
     int describe(char* buffer, size_t maxlen) const;
+
+    static void Init();
 };
 
 } // namespace js
 
 #endif /* js_SliceBudget_h */
--- a/js/public/UbiNode.h
+++ b/js/public/UbiNode.h
@@ -1105,19 +1105,17 @@ class JS_PUBLIC_API(Concrete<JSScript>) 
 
 // The JSObject specialization.
 template<>
 class JS_PUBLIC_API(Concrete<JSObject>) : public TracerConcrete<JSObject> {
   protected:
     explicit Concrete(JSObject* ptr) : TracerConcrete<JSObject>(ptr) { }
 
   public:
-    static void construct(void* storage, JSObject* ptr) {
-        new (storage) Concrete(ptr);
-    }
+    static void construct(void* storage, JSObject* ptr);
 
     JS::Compartment* compartment() const override;
     JS::Realm* realm() const override;
 
     const char* jsObjectClassName() const override;
     MOZ_MUST_USE bool jsObjectConstructorName(JSContext* cx, UniqueTwoByteChars& outName)
         const override;
     Size size(mozilla::MallocSizeOf mallocSizeOf) const override;
@@ -1160,16 +1158,25 @@ class JS_PUBLIC_API(Concrete<void>) : pu
     CoarseType coarseType() const final;
 
     explicit Concrete(void* ptr) : Base(ptr) { }
 
   public:
     static void construct(void* storage, void* ptr) { new (storage) Concrete(ptr); }
 };
 
+// The |callback| callback is much like the |Concrete<T>::construct| method: a call to
+// |callback| should construct an instance of the most appropriate JS::ubi::Base subclass
+// for |obj| in |storage|. The callback may assume that
+// |obj->getClass()->isDOMClass()|, and that |storage| refers to the
+// sizeof(JS::ubi::Base) bytes of space that all ubi::Base implementations should
+// require.
+
+// Set |cx|'s runtime hook for constructing ubi::Nodes for DOM classes to |callback|.
+void SetConstructUbiNodeForDOMObjectCallback(JSContext* cx, void (*callback)(void*, JSObject*));
 
 } // namespace ubi
 } // namespace JS
 
 namespace js {
 
 // Make ubi::Node::HashPolicy the default hash policy for ubi::Node.
 template<> struct DefaultHasher<JS::ubi::Node> : JS::ubi::Node::HashPolicy { };
--- a/js/public/UbiNodeUtils.h
+++ b/js/public/UbiNodeUtils.h
@@ -30,17 +30,17 @@ class SimpleEdgeRange : public EdgeRange
     }
 
   public:
     explicit SimpleEdgeRange() : edges(), i(0) { }
 
     bool addTracerEdges(JSRuntime* rt, void* thing, JS::TraceKind kind, bool wantNames);
 
     bool addEdge(Edge edge) {
-        if (!edge.name || !edges.append(std::move(edge)))
+        if(!edges.append(std::move(edge)))
             return false;
         settle();
         return true;
     }
 
     void popFront() override { i++; settle(); }
 };
 
deleted file mode 100644
--- a/js/src/builtin/SIMD.cpp
+++ /dev/null
@@ -1,1644 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sts=4 et sw=4 tw=99:
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * JS SIMD pseudo-module.
- * Specification matches polyfill:
- * https://github.com/johnmccutchan/ecmascript_simd/blob/master/src/ecmascript_simd.js
- * The objects float32x4 and int32x4 are installed on the SIMD pseudo-module.
- */
-
-#include "builtin/SIMD.h"
-
-#include "mozilla/FloatingPoint.h"
-#include "mozilla/IntegerTypeTraits.h"
-#include "mozilla/Sprintf.h"
-#include "mozilla/TypeTraits.h"
-
-#include "jsapi.h"
-#include "jsfriendapi.h"
-#include "jsnum.h"
-
-#include "builtin/TypedObject.h"
-#include "jit/AtomicOperations.h"
-#include "jit/InlinableNatives.h"
-#include "js/Value.h"
-
-#include "vm/JSObject-inl.h"
-
-using namespace js;
-
-using mozilla::IsNaN;
-using mozilla::EnableIf;
-using mozilla::IsIntegral;
-using mozilla::IsFloatingPoint;
-using mozilla::IsSigned;
-using mozilla::MakeUnsigned;
-
-///////////////////////////////////////////////////////////////////////////
-// SIMD
-
-static_assert(unsigned(SimdType::Count) == 12, "sync with TypedObjectConstants.h");
-
-static bool ArgumentToLaneIndex(JSContext* cx, JS::HandleValue v, unsigned limit, unsigned* lane);
-
-static bool
-CheckVectorObject(HandleValue v, SimdType expectedType)
-{
-    if (!v.isObject())
-        return false;
-
-    JSObject& obj = v.toObject();
-    if (!obj.is<TypedObject>())
-        return false;
-
-    TypeDescr& typeRepr = obj.as<TypedObject>().typeDescr();
-    if (typeRepr.kind() != type::Simd)
-        return false;
-
-    return typeRepr.as<SimdTypeDescr>().type() == expectedType;
-}
-
-template<class V>
-bool
-js::IsVectorObject(HandleValue v)
-{
-    return CheckVectorObject(v, V::type);
-}
-
-#define FOR_EACH_SIMD(macro) \
-  macro(Int8x16)             \
-  macro(Int16x8)             \
-  macro(Int32x4)             \
-  macro(Uint8x16)            \
-  macro(Uint16x8)            \
-  macro(Uint32x4)            \
-  macro(Float32x4)           \
-  macro(Float64x2)           \
-  macro(Bool8x16)            \
-  macro(Bool16x8)            \
-  macro(Bool32x4)            \
-  macro(Bool64x2)
-
-#define InstantiateIsVectorObject_(T) \
-    template bool js::IsVectorObject<T>(HandleValue v);
-FOR_EACH_SIMD(InstantiateIsVectorObject_)
-#undef InstantiateIsVectorObject_
-
-const char*
-js::SimdTypeToString(SimdType type)
-{
-    switch (type) {
-#define RETSTR_(TYPE) case SimdType::TYPE: return #TYPE;
-      FOR_EACH_SIMD(RETSTR_)
-#undef RETSTR_
-      case SimdType::Count: break;
-    }
-    return "<bad SimdType>";
-}
-
-PropertyName*
-js::SimdTypeToName(const JSAtomState& atoms, SimdType type)
-{
-    switch (type) {
-#define CASE_(TypeName) case SimdType::TypeName: return atoms.TypeName;
-      FOR_EACH_SIMD(CASE_)
-#undef CASE_
-      case SimdType::Count: break;
-    }
-    MOZ_CRASH("bad SIMD type");
-}
-
-bool
-js::IsSimdTypeName(const JSAtomState& atoms, const PropertyName* name, SimdType* type)
-{
-#define CHECK_(TypeName) if (name == atoms.TypeName) {   \
-                             *type = SimdType::TypeName; \
-                             return true;                \
-                         }
-    FOR_EACH_SIMD(CHECK_)
-#undef CHECK_
-    return false;
-}
-
-static inline bool
-ErrorBadArgs(JSContext* cx)
-{
-    JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS);
-    return false;
-}
-
-static inline bool
-ErrorWrongTypeArg(JSContext* cx, unsigned argIndex, Handle<TypeDescr*> typeDescr)
-{
-    MOZ_ASSERT(argIndex < 10);
-    char charArgIndex[2];
-    SprintfLiteral(charArgIndex, "%u", argIndex);
-
-    HeapSlot& typeNameSlot = typeDescr->getReservedSlotRef(JS_DESCR_SLOT_STRING_REPR);
-    char* typeNameStr = JS_EncodeString(cx, typeNameSlot.toString());
-    if (!typeNameStr)
-        return false;
-
-    JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_SIMD_NOT_A_VECTOR,
-                               typeNameStr, charArgIndex);
-    JS_free(cx, typeNameStr);
-    return false;
-}
-
-static inline bool
-ErrorBadIndex(JSContext* cx)
-{
-    JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_BAD_INDEX);
-    return false;
-}
-
-/* Non-standard: convert and range check an index value for SIMD operations.
- *
- *   1. numericIndex = ToNumber(argument)            (may throw TypeError)
- *   2. intIndex = ToInteger(numericIndex)
- *   3. if intIndex != numericIndex throw RangeError
- *
- * This function additionally bounds the range to the non-negative contiguous
- * integers:
- *
- *   4. if intIndex < 0 or intIndex > 2^53 throw RangeError
- *
- * Return true and set |*index| to the integer value if |argument| is a valid
- * array index argument. Otherwise report an TypeError or RangeError and return
- * false.
- *
- * The returned index will always be in the range 0 <= *index <= 2^53.
- */
-static bool
-NonStandardToIndex(JSContext* cx, HandleValue v, uint64_t* index)
-{
-    // Fast common case.
-    if (v.isInt32()) {
-        int32_t i = v.toInt32();
-        if (i >= 0) {
-            *index = i;
-            return true;
-        }
-    }
-
-    // Slow case. Use ToNumber() to coerce. This may throw a TypeError.
-    double d;
-    if (!ToNumber(cx, v, &d))
-        return false;
-
-    // Check that |d| is an integer in the valid range.
-    //
-    // Not all floating point integers fit in the range of a uint64_t, so we
-    // need a rough range check before the real range check in our caller. We
-    // could limit indexes to UINT64_MAX, but this would mean that our callers
-    // have to be very careful about integer overflow. The contiguous integer
-    // floating point numbers end at 2^53, so make that our upper limit. If we
-    // ever support arrays with more than 2^53 elements, this will need to
-    // change.
-    //
-    // Reject infinities, NaNs, and numbers outside the contiguous integer range
-    // with a RangeError.
-
-    // Write relation so NaNs throw a RangeError.
-    if (!(0 <= d && d <= (uint64_t(1) << 53))) {
-        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_BAD_INDEX);
-        return false;
-    }
-
-    // Check that d is an integer, throw a RangeError if not.
-    // Note that this conversion could invoke undefined behaviour without the
-    // range check above.
-    uint64_t i(d);
-    if (d != double(i)) {
-        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_BAD_INDEX);
-        return false;
-    }
-
-    *index = i;
-    return true;
-}
-
-template<typename T>
-static SimdTypeDescr*
-GetTypeDescr(JSContext* cx)
-{
-    RootedGlobalObject global(cx, cx->global());
-    return GlobalObject::getOrCreateSimdTypeDescr(cx, global, T::type);
-}
-
-template<typename V>
-bool
-js::ToSimdConstant(JSContext* cx, HandleValue v, jit::SimdConstant* out)
-{
-    typedef typename V::Elem Elem;
-    Rooted<TypeDescr*> typeDescr(cx, GetTypeDescr<V>(cx));
-    if (!typeDescr)
-        return false;
-    if (!IsVectorObject<V>(v))
-        return ErrorWrongTypeArg(cx, 1, typeDescr);
-
-    JS::AutoCheckCannotGC nogc(cx);
-    Elem* mem = reinterpret_cast<Elem*>(v.toObject().as<TypedObject>().typedMem(nogc));
-    *out = jit::SimdConstant::CreateSimd128(mem);
-    return true;
-}
-
-template bool js::ToSimdConstant<Int8x16>(JSContext* cx, HandleValue v, jit::SimdConstant* out);
-template bool js::ToSimdConstant<Int16x8>(JSContext* cx, HandleValue v, jit::SimdConstant* out);
-template bool js::ToSimdConstant<Int32x4>(JSContext* cx, HandleValue v, jit::SimdConstant* out);
-template bool js::ToSimdConstant<Float32x4>(JSContext* cx, HandleValue v, jit::SimdConstant* out);
-template bool js::ToSimdConstant<Bool8x16>(JSContext* cx, HandleValue v, jit::SimdConstant* out);
-template bool js::ToSimdConstant<Bool16x8>(JSContext* cx, HandleValue v, jit::SimdConstant* out);
-template bool js::ToSimdConstant<Bool32x4>(JSContext* cx, HandleValue v, jit::SimdConstant* out);
-
-template<typename Elem>
-static Elem
-TypedObjectMemory(HandleValue v, const JS::AutoRequireNoGC& nogc)
-{
-    TypedObject& obj = v.toObject().as<TypedObject>();
-    return reinterpret_cast<Elem>(obj.typedMem(nogc));
-}
-
-static const ClassOps SimdTypeDescrClassOps = {
-    nullptr, /* addProperty */
-    nullptr, /* delProperty */
-    nullptr, /* enumerate */
-    nullptr, /* newEnumerate */
-    nullptr, /* resolve */
-    nullptr, /* mayResolve */
-    TypeDescr::finalize,
-    SimdTypeDescr::call
-};
-
-const Class SimdTypeDescr::class_ = {
-    "SIMD",
-    JSCLASS_HAS_RESERVED_SLOTS(JS_DESCR_SLOTS) | JSCLASS_BACKGROUND_FINALIZE,
-    &SimdTypeDescrClassOps
-};
-
-namespace {
-
-// Define classes (Int8x16Defn, Int16x8Defn, etc.) to group together various
-// properties and so on.
-#define DEFINE_DEFN_(TypeName)                                       \
-class TypeName##Defn {                                               \
-  public:                                                            \
-    static const JSFunctionSpec Methods[];                           \
-};
-
-FOR_EACH_SIMD(DEFINE_DEFN_)
-#undef DEFINE_DEFN_
-
-} // namespace
-
-// Shared type descriptor methods for all SIMD types.
-static const JSFunctionSpec TypeDescriptorMethods[] = {
-    JS_SELF_HOSTED_FN("toSource", "DescrToSource", 0, 0),
-    JS_SELF_HOSTED_FN("array", "ArrayShorthand", 1, 0),
-    JS_SELF_HOSTED_FN("equivalent", "TypeDescrEquivalent", 1, 0),
-    JS_FS_END
-};
-
-// Shared TypedObject methods for all SIMD types.
-static const JSFunctionSpec SimdTypedObjectMethods[] = {
-    JS_SELF_HOSTED_FN("toString", "SimdToString", 0, 0),
-    JS_SELF_HOSTED_FN("valueOf", "SimdValueOf", 0, 0),
-    JS_SELF_HOSTED_FN("toSource", "SimdToSource", 0, 0),
-    JS_FS_END
-};
-
-// Provide JSJitInfo structs for those types that are supported by Ion.
-// The controlling SIMD type is encoded as the InlinableNative primary opcode.
-// The SimdOperation within the type is encoded in the .depth field.
-//
-// The JS_INLINABLE_FN macro refers to js::JitInfo_##native which we provide as
-// Simd##Type##_##Operation
-//
-// /!\ Don't forget to keep this list in sync with the SIMD instrinics used in
-// SelfHosting.cpp.
-
-namespace js {
-namespace jit {
-
-static_assert(uint64_t(SimdOperation::Last) <= UINT16_MAX, "SimdOperation must fit in uint16_t");
-
-// See also JitInfo_* in MCallOptimize.cpp. We provide a JSJitInfo for all the
-// named functions here. The default JitInfo_SimdInt32x4 etc structs represent the
-// SimdOperation::Constructor.
-#define DEFN(TYPE, OP) const JSJitInfo JitInfo_Simd##TYPE##_##OP = {                             \
-     /* .getter, unused for inlinable natives. */                                                \
-    { nullptr },                                                                                 \
-    /* .inlinableNative, but we have to init first union member: .protoID. */                    \
-    { uint16_t(InlinableNative::Simd##TYPE) },                                                   \
-    /* .nativeOp. Actually initializing first union member .depth. */                            \
-    { uint16_t(SimdOperation::Fn_##OP) },                                                        \
-    /* .type_ bitfield says this in an inlinable native function. */                             \
-    JSJitInfo::InlinableNative                                                                   \
-    /* Remaining fields are not used for inlinable natives. They are zero-initialized. */        \
-};
-
-// This list of inlinable types should match the one in jit/InlinableNatives.h.
-#define TDEFN(Name, Func, Operands) DEFN(Float32x4, Name)
-FLOAT32X4_FUNCTION_LIST(TDEFN)
-#undef TDEFN
-
-#define TDEFN(Name, Func, Operands) DEFN(Int8x16, Name)
-INT8X16_FUNCTION_LIST(TDEFN)
-#undef TDEFN
-
-#define TDEFN(Name, Func, Operands) DEFN(Uint8x16, Name)
-UINT8X16_FUNCTION_LIST(TDEFN)
-#undef TDEFN
-
-#define TDEFN(Name, Func, Operands) DEFN(Int16x8, Name)
-INT16X8_FUNCTION_LIST(TDEFN)
-#undef TDEFN
-
-#define TDEFN(Name, Func, Operands) DEFN(Uint16x8, Name)
-UINT16X8_FUNCTION_LIST(TDEFN)
-#undef TDEFN
-
-#define TDEFN(Name, Func, Operands) DEFN(Int32x4, Name)
-INT32X4_FUNCTION_LIST(TDEFN)
-#undef TDEFN
-
-#define TDEFN(Name, Func, Operands) DEFN(Uint32x4, Name)
-UINT32X4_FUNCTION_LIST(TDEFN)
-#undef TDEFN
-
-#define TDEFN(Name, Func, Operands) DEFN(Bool8x16, Name)
-BOOL8X16_FUNCTION_LIST(TDEFN)
-#undef TDEFN
-
-#define TDEFN(Name, Func, Operands) DEFN(Bool16x8, Name)
-BOOL16X8_FUNCTION_LIST(TDEFN)
-#undef TDEFN
-
-#define TDEFN(Name, Func, Operands) DEFN(Bool32x4, Name)
-BOOL32X4_FUNCTION_LIST(TDEFN)
-#undef TDEFN
-
-} // namespace jit
-} // namespace js
-
-const JSFunctionSpec Float32x4Defn::Methods[] = {
-#define SIMD_FLOAT32X4_FUNCTION_ITEM(Name, Func, Operands) \
-    JS_INLINABLE_FN(#Name, js::simd_float32x4_##Name, Operands, 0, SimdFloat32x4_##Name),
-    FLOAT32X4_FUNCTION_LIST(SIMD_FLOAT32X4_FUNCTION_ITEM)
-#undef SIMD_FLOAT32x4_FUNCTION_ITEM
-    JS_FS_END
-};
-
-const JSFunctionSpec Float64x2Defn::Methods[]  = {
-#define SIMD_FLOAT64X2_FUNCTION_ITEM(Name, Func, Operands) \
-    JS_FN(#Name, js::simd_float64x2_##Name, Operands, 0),
-    FLOAT64X2_FUNCTION_LIST(SIMD_FLOAT64X2_FUNCTION_ITEM)
-#undef SIMD_FLOAT64X2_FUNCTION_ITEM
-    JS_FS_END
-};
-
-const JSFunctionSpec Int8x16Defn::Methods[] = {
-#define SIMD_INT8X16_FUNCTION_ITEM(Name, Func, Operands) \
-    JS_INLINABLE_FN(#Name, js::simd_int8x16_##Name, Operands, 0, SimdInt8x16_##Name),
-    INT8X16_FUNCTION_LIST(SIMD_INT8X16_FUNCTION_ITEM)
-#undef SIMD_INT8X16_FUNCTION_ITEM
-    JS_FS_END
-};
-
-const JSFunctionSpec Int16x8Defn::Methods[] = {
-#define SIMD_INT16X8_FUNCTION_ITEM(Name, Func, Operands) \
-    JS_INLINABLE_FN(#Name, js::simd_int16x8_##Name, Operands, 0, SimdInt16x8_##Name),
-    INT16X8_FUNCTION_LIST(SIMD_INT16X8_FUNCTION_ITEM)
-#undef SIMD_INT16X8_FUNCTION_ITEM
-    JS_FS_END
-};
-
-const JSFunctionSpec Int32x4Defn::Methods[] = {
-#define SIMD_INT32X4_FUNCTION_ITEM(Name, Func, Operands) \
-    JS_INLINABLE_FN(#Name, js::simd_int32x4_##Name, Operands, 0, SimdInt32x4_##Name),
-    INT32X4_FUNCTION_LIST(SIMD_INT32X4_FUNCTION_ITEM)
-#undef SIMD_INT32X4_FUNCTION_ITEM
-    JS_FS_END
-};
-
-const JSFunctionSpec Uint8x16Defn::Methods[] = {
-#define SIMD_UINT8X16_FUNCTION_ITEM(Name, Func, Operands) \
-    JS_INLINABLE_FN(#Name, js::simd_uint8x16_##Name, Operands, 0, SimdUint8x16_##Name),
-    UINT8X16_FUNCTION_LIST(SIMD_UINT8X16_FUNCTION_ITEM)
-#undef SIMD_UINT8X16_FUNCTION_ITEM
-    JS_FS_END
-};
-
-const JSFunctionSpec Uint16x8Defn::Methods[] = {
-#define SIMD_UINT16X8_FUNCTION_ITEM(Name, Func, Operands) \
-    JS_INLINABLE_FN(#Name, js::simd_uint16x8_##Name, Operands, 0, SimdUint16x8_##Name),
-    UINT16X8_FUNCTION_LIST(SIMD_UINT16X8_FUNCTION_ITEM)
-#undef SIMD_UINT16X8_FUNCTION_ITEM
-    JS_FS_END
-};
-
-const JSFunctionSpec Uint32x4Defn::Methods[] = {
-#define SIMD_UINT32X4_FUNCTION_ITEM(Name, Func, Operands) \
-    JS_INLINABLE_FN(#Name, js::simd_uint32x4_##Name, Operands, 0, SimdUint32x4_##Name),
-    UINT32X4_FUNCTION_LIST(SIMD_UINT32X4_FUNCTION_ITEM)
-#undef SIMD_UINT32X4_FUNCTION_ITEM
-    JS_FS_END
-};
-
-const JSFunctionSpec Bool8x16Defn::Methods[] = {
-#define SIMD_BOOL8X16_FUNCTION_ITEM(Name, Func, Operands) \
-    JS_INLINABLE_FN(#Name, js::simd_bool8x16_##Name, Operands, 0, SimdBool8x16_##Name),
-    BOOL8X16_FUNCTION_LIST(SIMD_BOOL8X16_FUNCTION_ITEM)
-#undef SIMD_BOOL8X16_FUNCTION_ITEM
-    JS_FS_END
-};
-
-const JSFunctionSpec Bool16x8Defn::Methods[] = {
-#define SIMD_BOOL16X8_FUNCTION_ITEM(Name, Func, Operands) \
-    JS_INLINABLE_FN(#Name, js::simd_bool16x8_##Name, Operands, 0, SimdBool16x8_##Name),
-    BOOL16X8_FUNCTION_LIST(SIMD_BOOL16X8_FUNCTION_ITEM)
-#undef SIMD_BOOL16X8_FUNCTION_ITEM
-    JS_FS_END
-};
-
-const JSFunctionSpec Bool32x4Defn::Methods[] = {
-#define SIMD_BOOL32X4_FUNCTION_ITEM(Name, Func, Operands) \
-    JS_INLINABLE_FN(#Name, js::simd_bool32x4_##Name, Operands, 0, SimdBool32x4_##Name),
-    BOOL32X4_FUNCTION_LIST(SIMD_BOOL32X4_FUNCTION_ITEM)
-#undef SIMD_BOOL32X4_FUNCTION_ITEM
-    JS_FS_END
-};
-
-const JSFunctionSpec Bool64x2Defn::Methods[] = {
-#define SIMD_BOOL64X2_FUNCTION_ITEM(Name, Func, Operands) \
-    JS_FN(#Name, js::simd_bool64x2_##Name, Operands, 0),
-    BOOL64X2_FUNCTION_LIST(SIMD_BOOL64X2_FUNCTION_ITEM)
-#undef SIMD_BOOL64x2_FUNCTION_ITEM
-    JS_FS_END
-};
-
-template <typename T>
-static bool
-FillLanes(JSContext* cx, Handle<TypedObject*> result, const CallArgs& args)
-{
-    typedef typename T::Elem Elem;
-    Elem tmp;
-    for (unsigned i = 0; i < T::lanes; i++) {
-        if (!T::Cast(cx, args.get(i), &tmp))
-            return false;
-        // Reassure typedMem() that we won't GC while holding onto the returned
-        // pointer, even though we could GC on every iteration of this loop
-        // (but it is safe because we re-fetch each time.)
-        JS::AutoCheckCannotGC nogc(cx);
-        reinterpret_cast<Elem*>(result->typedMem(nogc))[i] = tmp;
-    }
-    args.rval().setObject(*result);
-    return true;
-}
-
-bool
-SimdTypeDescr::call(JSContext* cx, unsigned argc, Value* vp)
-{
-    CallArgs args = CallArgsFromVp(argc, vp);
-
-    Rooted<SimdTypeDescr*> descr(cx, &args.callee().as<SimdTypeDescr>());
-    Rooted<TypedObject*> result(cx, TypedObject::createZeroed(cx, descr));
-    if (!result)
-        return false;
-
-#define CASE_CALL_(Type) \
-      case SimdType::Type:   return FillLanes< ::Type>(cx, result, args);
-
-    switch (descr->type()) {
-      FOR_EACH_SIMD(CASE_CALL_)
-      case SimdType::Count: break;
-    }
-
-#undef CASE_CALL_
-    MOZ_CRASH("unexpected SIMD descriptor");
-    return false;
-}
-
-///////////////////////////////////////////////////////////////////////////
-// SIMD class
-
-static const ClassOps SimdObjectClassOps = {
-    nullptr, /* addProperty */
-    nullptr, /* delProperty */
-    nullptr, /* enumerate */
-    nullptr, /* newEnumerate */
-    SimdObject::resolve
-};
-
-const Class SimdObject::class_ = {
-    "SIMD",
-    JSCLASS_HAS_RESERVED_SLOTS(uint32_t(SimdType::Count)),
-    &SimdObjectClassOps
-};
-
-/* static */ bool
-GlobalObject::initSimdObject(JSContext* cx, Handle<GlobalObject*> global)
-{
-    // SIMD relies on the TypedObject module being initialized.
-    // In particular, the self-hosted code for array() wants
-    // to be able to call GetTypedObjectModule(). It is NOT necessary
-    // to install the TypedObjectModule global, but at the moment
-    // those two things are not separable.
-    if (!GlobalObject::getOrCreateTypedObjectModule(cx, global))
-        return false;
-
-    RootedObject globalSimdObject(cx);
-    RootedObject objProto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global));
-    if (!objProto)
-        return false;
-
-    globalSimdObject = NewObjectWithGivenProto(cx, &SimdObject::class_, objProto, SingletonObject);
-    if (!globalSimdObject)
-        return false;
-
-    RootedValue globalSimdValue(cx, ObjectValue(*globalSimdObject));
-    if (!DefineDataProperty(cx, global, cx->names().SIMD, globalSimdValue, JSPROP_RESOLVING))
-        return false;
-
-    global->setConstructor(JSProto_SIMD, globalSimdValue);
-    return true;
-}
-
-static bool
-CreateSimdType(JSContext* cx, Handle<GlobalObject*> global, HandlePropertyName stringRepr,
-               SimdType simdType, const JSFunctionSpec* methods)
-{
-    RootedObject funcProto(cx, GlobalObject::getOrCreateFunctionPrototype(cx, global));
-    if (!funcProto)
-        return false;
-
-    // Create type constructor itself and initialize its reserved slots.
-    Rooted<SimdTypeDescr*> typeDescr(cx);
-    typeDescr = NewObjectWithGivenProto<SimdTypeDescr>(cx, funcProto, SingletonObject);
-    if (!typeDescr)
-        return false;
-
-    typeDescr->initReservedSlot(JS_DESCR_SLOT_KIND, Int32Value(type::Simd));
-    typeDescr->initReservedSlot(JS_DESCR_SLOT_STRING_REPR, StringValue(stringRepr));
-    typeDescr->initReservedSlot(JS_DESCR_SLOT_ALIGNMENT, Int32Value(SimdTypeDescr::alignment(simdType)));
-    typeDescr->initReservedSlot(JS_DESCR_SLOT_SIZE, Int32Value(SimdTypeDescr::size(simdType)));
-    typeDescr->initReservedSlot(JS_DESCR_SLOT_OPAQUE, BooleanValue(false));
-    typeDescr->initReservedSlot(JS_DESCR_SLOT_TYPE, Int32Value(uint8_t(simdType)));
-
-    if (!CreateUserSizeAndAlignmentProperties(cx, typeDescr))
-        return false;
-
-    // Create prototype property, which inherits from Object.prototype.
-    RootedObject objProto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global));
-    if (!objProto)
-        return false;
-    Rooted<TypedProto*> proto(cx);
-    proto = NewObjectWithGivenProto<TypedProto>(cx, objProto, SingletonObject);
-    if (!proto)
-        return false;
-    typeDescr->initReservedSlot(JS_DESCR_SLOT_TYPROTO, ObjectValue(*proto));
-
-    // Link constructor to prototype and install properties.
-    if (!JS_DefineFunctions(cx, typeDescr, TypeDescriptorMethods))
-        return false;
-
-    if (!LinkConstructorAndPrototype(cx, typeDescr, proto) ||
-        !JS_DefineFunctions(cx, proto, SimdTypedObjectMethods))
-    {
-        return false;
-    }
-
-    // Bind type descriptor to the global SIMD object
-    RootedObject globalSimdObject(cx, GlobalObject::getOrCreateSimdGlobalObject(cx, global));
-    MOZ_ASSERT(globalSimdObject);
-
-    RootedValue typeValue(cx, ObjectValue(*typeDescr));
-    if (!JS_DefineFunctions(cx, typeDescr, methods) ||
-        !DefineDataProperty(cx, globalSimdObject, stringRepr, typeValue,
-                            JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_RESOLVING))
-    {
-        return false;
-    }
-
-    uint32_t slot = uint32_t(typeDescr->type());
-    MOZ_ASSERT(globalSimdObject->as<NativeObject>().getReservedSlot(slot).isUndefined());
-    globalSimdObject->as<NativeObject>().setReservedSlot(slot, ObjectValue(*typeDescr));
-    return !!typeDescr;
-}
-
-/* static */ bool
-GlobalObject::initSimdType(JSContext* cx, Handle<GlobalObject*> global, SimdType simdType)
-{
-#define CREATE_(Type) \
-    case SimdType::Type: \
-      return CreateSimdType(cx, global, cx->names().Type, simdType, Type##Defn::Methods);
-
-    switch (simdType) {
-      FOR_EACH_SIMD(CREATE_)
-      case SimdType::Count: break;
-    }
-    MOZ_CRASH("unexpected simd type");
-
-#undef CREATE_
-}
-
-/* static */ SimdTypeDescr*
-GlobalObject::getOrCreateSimdTypeDescr(JSContext* cx, Handle<GlobalObject*> global,
-                                       SimdType simdType)
-{
-    MOZ_ASSERT(unsigned(simdType) < unsigned(SimdType::Count), "Invalid SIMD type");
-
-    RootedObject globalSimdObject(cx, GlobalObject::getOrCreateSimdGlobalObject(cx, global));
-    if (!globalSimdObject)
-       return nullptr;
-
-    uint32_t typeSlotIndex = uint32_t(simdType);
-    if (globalSimdObject->as<NativeObject>().getReservedSlot(typeSlotIndex).isUndefined() &&
-        !GlobalObject::initSimdType(cx, global, simdType))
-    {
-        return nullptr;
-    }
-
-    const Value& slot = globalSimdObject->as<NativeObject>().getReservedSlot(typeSlotIndex);
-    MOZ_ASSERT(slot.isObject());
-    return &slot.toObject().as<SimdTypeDescr>();
-}
-
-bool
-SimdObject::resolve(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* resolved)
-{
-    *resolved = false;
-    if (!JSID_IS_ATOM(id))
-        return true;
-    JSAtom* str = JSID_TO_ATOM(id);
-    Rooted<GlobalObject*> global(cx, cx->global());
-#define TRY_RESOLVE_(Type)                                                    \
-    if (str == cx->names().Type) {                                            \
-        *resolved = CreateSimdType(cx, global, cx->names().Type,              \
-                                   SimdType::Type, Type##Defn::Methods);      \
-        return *resolved;                                                     \
-    }
-    FOR_EACH_SIMD(TRY_RESOLVE_)
-#undef TRY_RESOLVE_
-    return true;
-}
-
-JSObject*
-js::InitSimdClass(JSContext* cx, Handle<GlobalObject*> global)
-{
-    return GlobalObject::getOrCreateSimdGlobalObject(cx, global);
-}
-
-template<typename V>
-JSObject*
-js::CreateSimd(JSContext* cx, const typename V::Elem* data)
-{
-    typedef typename V::Elem Elem;
-    Rooted<TypeDescr*> typeDescr(cx, GetTypeDescr<V>(cx));
-    if (!typeDescr)
-        return nullptr;
-
-    Rooted<TypedObject*> result(cx, TypedObject::createZeroed(cx, typeDescr));
-    if (!result)
-        return nullptr;
-
-    JS::AutoCheckCannotGC nogc(cx);
-    Elem* resultMem = reinterpret_cast<Elem*>(result->typedMem(nogc));
-    memcpy(resultMem, data, sizeof(Elem) * V::lanes);
-    return result;
-}
-
-#define InstantiateCreateSimd_(Type) \
-    template JSObject* js::CreateSimd<Type>(JSContext* cx, const Type::Elem* data);
-
-FOR_EACH_SIMD(InstantiateCreateSimd_)
-
-#undef InstantiateCreateSimd_
-
-#undef FOR_EACH_SIMD
-
-namespace js {
-
-namespace detail {
-
-template<typename T, typename Enable = void>
-struct MaybeMakeUnsigned {
-    using Type = T;
-};
-
-template<typename T>
-struct MaybeMakeUnsigned<T, typename EnableIf<IsIntegral<T>::value && IsSigned<T>::value>::Type> {
-    using Type = typename MakeUnsigned<T>::Type;
-};
-
-} // namespace detail
-
-// Unary SIMD operators
-template<typename T>
-struct Identity {
-    static T apply(T x) { return x; }
-};
-template<typename T>
-struct Abs {
-    static T apply(T x) { return mozilla::Abs(x); }
-};
-template<typename T>
-struct Neg {
-    using MaybeUnsignedT = typename detail::MaybeMakeUnsigned<T>::Type;
-    static T apply(T x) {
-        // Prepend |1U| to force integral promotion through *unsigned* types.
-        // Otherwise when |T = uint16_t| and |int| is 32-bit, we could have
-        // |uint16_t(-1) * uint16_t(65535)| which would really be
-        // |int(65535) * int(65535)|, but as |4294836225 > 2147483647| would
-        // perform signed integer overflow.
-        // https://stackoverflow.com/questions/24795651/whats-the-best-c-way-to-multiply-unsigned-integers-modularly-safely
-        return static_cast<MaybeUnsignedT>(1U * MaybeUnsignedT(-1) * MaybeUnsignedT(x));
-    }
-};
-template<typename T>
-struct Not {
-    static T apply(T x) { return ~x; }
-};
-template<typename T>
-struct LogicalNot {
-    static T apply(T x) { return !x; }
-};
-template<typename T>
-struct RecApprox {
-    static_assert(IsFloatingPoint<T>::value, "RecApprox only supported for floating points");
-    static T apply(T x) { return 1 / x; }
-};
-template<typename T>
-struct RecSqrtApprox {
-    static_assert(IsFloatingPoint<T>::value, "RecSqrtApprox only supported for floating points");
-    static T apply(T x) { return 1 / sqrt(x); }
-};
-template<typename T>
-struct Sqrt {
-    static_assert(IsFloatingPoint<T>::value, "Sqrt only supported for floating points");
-    static T apply(T x) { return sqrt(x); }
-};
-
-// Binary SIMD operators
-template<typename T>
-struct Add {
-    using MaybeUnsignedT = typename detail::MaybeMakeUnsigned<T>::Type;
-    static T apply(T l, T r) { return MaybeUnsignedT(l) + MaybeUnsignedT(r); }
-};
-template<typename T>
-struct Sub {
-    using MaybeUnsignedT = typename detail::MaybeMakeUnsigned<T>::Type;
-    static T apply(T l, T r) { return MaybeUnsignedT(l) - MaybeUnsignedT(r); }
-};
-template<typename T>
-struct Div {
-    static_assert(IsFloatingPoint<T>::value, "Div only supported for floating points");
-    static T apply(T l, T r) { return l / r; }
-};
-template<typename T>
-struct Mul {
-    using MaybeUnsignedT = typename detail::MaybeMakeUnsigned<T>::Type;
-    static T apply(T l, T r) { return MaybeUnsignedT(l) * MaybeUnsignedT(r); }
-};
-template<typename T>
-struct Minimum {
-    static T apply(T l, T r) { return math_min_impl(l, r); }
-};
-template<typename T>
-struct MinNum {
-    static T apply(T l, T r) { return IsNaN(l) ? r : (IsNaN(r) ? l : math_min_impl(l, r)); }
-};
-template<typename T>
-struct Maximum {
-    static T apply(T l, T r) { return math_max_impl(l, r); }
-};
-template<typename T>
-struct MaxNum {
-    static T apply(T l, T r) { return IsNaN(l) ? r : (IsNaN(r) ? l : math_max_impl(l, r)); }
-};
-template<typename T>
-struct LessThan {
-    static bool apply(T l, T r) { return l < r; }
-};
-template<typename T>
-struct LessThanOrEqual {
-    static bool apply(T l, T r) { return l <= r; }
-};
-template<typename T>
-struct GreaterThan {
-    static bool apply(T l, T r) { return l > r; }
-};
-template<typename T>
-struct GreaterThanOrEqual {
-    static bool apply(T l, T r) { return l >= r; }
-};
-template<typename T>
-struct Equal {
-    static bool apply(T l, T r) { return l == r; }
-};
-template<typename T>
-struct NotEqual {
-    static bool apply(T l, T r) { return l != r; }
-};
-template<typename T>
-struct Xor {
-    static T apply(T l, T r) { return l ^ r; }
-};
-template<typename T>
-struct And {
-    static T apply(T l, T r) { return l & r; }
-};
-template<typename T>
-struct Or {
-    static T apply(T l, T r) { return l | r; }
-};
-
-// For the following three operators, if the value v we're trying to shift is
-// such that v << bits can't fit in the int32 range, then we have undefined
-// behavior, according to C++11 [expr.shift]p2. However, left-shifting an
-// unsigned type is well-defined.
-//
-// In C++, shifting by an amount outside the range [0;N-1] is undefined
-// behavior. SIMD.js reduces the shift amount modulo the number of bits in a
-// lane and has defined behavior for all shift amounts.
-template<typename T>
-struct ShiftLeft {
-    static T apply(T v, int32_t bits) {
-        typedef typename mozilla::MakeUnsigned<T>::Type UnsignedT;
-        uint32_t maskedBits = uint32_t(bits) % (sizeof(T) * 8);
-        return UnsignedT(v) << maskedBits;
-    }
-};
-template<typename T>
-struct ShiftRightArithmetic {
-    static T apply(T v, int32_t bits) {
-        typedef typename mozilla::MakeSigned<T>::Type SignedT;
-        uint32_t maskedBits = uint32_t(bits) % (sizeof(T) * 8);
-        return SignedT(v) >> maskedBits;
-    }
-};
-template<typename T>
-struct ShiftRightLogical {
-    static T apply(T v, int32_t bits) {
-        typedef typename mozilla::MakeUnsigned<T>::Type UnsignedT;
-        uint32_t maskedBits = uint32_t(bits) % (sizeof(T) * 8);
-        return UnsignedT(v) >> maskedBits;
-    }
-};
-
-// Saturating arithmetic is only defined on types smaller than int.
-// Clamp `x` into the range supported by the integral type T.
-template<typename T>
-static T
-Saturate(int x)
-{
-    static_assert(mozilla::IsIntegral<T>::value, "Only integer saturation supported");
-    static_assert(sizeof(T) < sizeof(int), "Saturating int-sized arithmetic is not safe");
-    const T lower = mozilla::MinValue<T>::value;
-    const T upper = mozilla::MaxValue<T>::value;
-    if (x > int(upper))
-        return upper;
-    if (x < int(lower))
-        return lower;
-    return T(x);
-}
-
-// Since signed integer overflow is undefined behavior in C++, it would be
-// wildly irresponsible to attempt something as dangerous as adding two numbers
-// coming from user code. However, in this case we know that T is smaller than
-// int, so there is no way these operations can cause overflow. The
-// static_assert in Saturate() enforces this for us.
-template<typename T>
-struct AddSaturate {
-    static T apply(T l, T r) { return Saturate<T>(l + r); }
-};
-template<typename T>
-struct SubSaturate {
-    static T apply(T l, T r) { return Saturate<T>(l - r); }
-};
-
-} // namespace js
-
-template<typename Out>
-static bool
-StoreResult(JSContext* cx, CallArgs& args, typename Out::Elem* result)
-{
-    RootedObject obj(cx, CreateSimd<Out>(cx, result));
-    if (!obj)
-        return false;
-    args.rval().setObject(*obj);
-    return true;
-}
-
-// StoreResult can GC, and it is commonly used after pulling something out of a
-// TypedObject:
-//
-//   Elem result = op(TypedObjectMemory<Elem>(args[0]));
-//   StoreResult<Out>(..., result);
-//
-// The pointer extracted from the typed object in args[0] in the above example
-// could be an interior pointer, and therefore be invalidated by GC.
-// TypedObjectMemory() requires an assertion token to be passed in to prove
-// that we won't GC, but the scope of eg an AutoCheckCannotGC RAII object
-// extends to the end of its containing scope -- which would include the call
-// to StoreResult, resulting in a rooting hazard.
-//
-// TypedObjectElemArray fixes this by wrapping the problematic pointer in a
-// type, and the analysis is able to see that it is dead before calling
-// StoreResult. (But if another GC called is made before the pointer is dead,
-// it will correctly report a hazard.)
-//
-template <typename Elem>
-class TypedObjectElemArray {
-    Elem* elements;
-  public:
-    explicit TypedObjectElemArray(HandleValue objVal) {
-        JS::AutoCheckCannotGC nogc;
-        elements = TypedObjectMemory<Elem*>(objVal, nogc);
-    }
-    Elem& operator[](int i) { return elements[i]; }
-} JS_HAZ_GC_POINTER;
-
-// Coerces the inputs of type In to the type Coercion, apply the operator Op
-// and converts the result to the type Out.
-template<typename In, typename Coercion, template<typename C> class Op, typename Out>
-static bool
-CoercedUnaryFunc(JSContext* cx, unsigned argc, Value* vp)
-{
-    typedef typename Coercion::Elem CoercionElem;
-    typedef typename Out::Elem RetElem;
-
-    CallArgs args = CallArgsFromVp(argc, vp);
-    if (args.length() != 1 || !IsVectorObject<In>(args[0]))
-        return ErrorBadArgs(cx);
-
-    CoercionElem result[Coercion::lanes];
-    TypedObjectElemArray<CoercionElem> val(args[0]);
-    for (unsigned i = 0; i < Coercion::lanes; i++)
-        result[i] = Op<CoercionElem>::apply(val[i]);
-    return StoreResult<Out>(cx, args, (RetElem*) result);
-}
-
-// Coerces the inputs of type In to the type Coercion, apply the operator Op
-// and converts the result to the type Out.
-template<typename In, typename Coercion, template<typename C> class Op, typename Out>
-static bool
-CoercedBinaryFunc(JSContext* cx, unsigned argc, Value* vp)
-{
-    typedef typename Coercion::Elem CoercionElem;
-    typedef typename Out::Elem RetElem;
-
-    CallArgs args = CallArgsFromVp(argc, vp);
-    if (args.length() != 2 || !IsVectorObject<In>(args[0]) || !IsVectorObject<In>(args[1]))
-        return ErrorBadArgs(cx);
-
-    CoercionElem result[Coercion::lanes];
-    TypedObjectElemArray<CoercionElem> left(args[0]);
-    TypedObjectElemArray<CoercionElem> right(args[1]);
-    for (unsigned i = 0; i < Coercion::lanes; i++)
-        result[i] = Op<CoercionElem>::apply(left[i], right[i]);
-    return StoreResult<Out>(cx, args, (RetElem*) result);
-}
-
-// Same as above, with no coercion, i.e. Coercion == In.
-template<typename In, template<typename C> class Op, typename Out>
-static bool
-UnaryFunc(JSContext* cx, unsigned argc, Value* vp)
-{
-    return CoercedUnaryFunc<In, Out, Op, Out>(cx, argc, vp);
-}
-
-template<typename In, template<typename C> class Op, typename Out>
-static bool
-BinaryFunc(JSContext* cx, unsigned argc, Value* vp)
-{
-    return CoercedBinaryFunc<In, Out, Op, Out>(cx, argc, vp);
-}
-
-template<typename V>
-static bool
-ExtractLane(JSContext* cx, unsigned argc, Value* vp)
-{
-    typedef typename V::Elem Elem;
-
-    CallArgs args = CallArgsFromVp(argc, vp);
-    if (args.length() < 2 || !IsVectorObject<V>(args[0]))
-        return ErrorBadArgs(cx);
-
-    unsigned lane;
-    if (!ArgumentToLaneIndex(cx, args[1], V::lanes, &lane))
-        return false;
-
-    JS::AutoCheckCannotGC nogc(cx);
-    Elem* vec = TypedObjectMemory<Elem*>(args[0], nogc);
-    Elem val = vec[lane];
-    args.rval().set(V::ToValue(val));
-    return true;
-}
-
-template<typename V>
-static bool
-AllTrue(JSContext* cx, unsigned argc, Value* vp)
-{
-    typedef typename V::Elem Elem;
-
-    CallArgs args = CallArgsFromVp(argc, vp);
-    if (args.length() < 1 || !IsVectorObject<V>(args[0]))
-        return ErrorBadArgs(cx);
-
-    JS::AutoCheckCannotGC nogc(cx);
-    Elem* vec = TypedObjectMemory<Elem*>(args[0], nogc);
-    bool allTrue = true;
-    for (unsigned i = 0; allTrue && i < V::lanes; i++)
-        allTrue = vec[i];
-
-    args.rval().setBoolean(allTrue);
-    return true;
-}
-
-template<typename V>
-static bool
-AnyTrue(JSContext* cx, unsigned argc, Value* vp)
-{
-    typedef typename V::Elem Elem;
-
-    CallArgs args = CallArgsFromVp(argc, vp);
-    if (args.length() < 1 || !IsVectorObject<V>(args[0]))
-        return ErrorBadArgs(cx);
-
-    JS::AutoCheckCannotGC nogc(cx);
-    Elem* vec = TypedObjectMemory<Elem*>(args[0], nogc);
-    bool anyTrue = false;
-    for (unsigned i = 0; !anyTrue && i < V::lanes; i++)
-        anyTrue = vec[i];
-
-    args.rval().setBoolean(anyTrue);
-    return true;
-}
-
-template<typename V>
-static bool
-ReplaceLane(JSContext* cx, unsigned argc, Value* vp)
-{
-    typedef typename V::Elem Elem;
-
-    CallArgs args = CallArgsFromVp(argc, vp);
-    // Only the first and second arguments are mandatory
-    if (args.length() < 2 || !IsVectorObject<V>(args[0]))
-        return ErrorBadArgs(cx);
-
-    unsigned lane;
-    if (!ArgumentToLaneIndex(cx, args[1], V::lanes, &lane))
-        return false;
-
-    Elem value;
-    if (!V::Cast(cx, args.get(2), &value))
-        return false;
-
-    TypedObjectElemArray<Elem> vec(args[0]);
-    Elem result[V::lanes];
-    for (unsigned i = 0; i < V::lanes; i++)
-        result[i] = i == lane ? value : vec[i];
-
-    return StoreResult<V>(cx, args, result);
-}
-
-template<typename V>
-static bool
-Swizzle(JSContext* cx, unsigned argc, Value* vp)
-{
-    typedef typename V::Elem Elem;
-
-    CallArgs args = CallArgsFromVp(argc, vp);
-    if (args.length() != (V::lanes + 1) || !IsVectorObject<V>(args[0]))
-        return ErrorBadArgs(cx);
-
-    unsigned lanes[V::lanes];
-    for (unsigned i = 0; i < V::lanes; i++) {
-        if (!ArgumentToLaneIndex(cx, args[i + 1], V::lanes, &lanes[i]))
-            return false;
-    }
-
-    TypedObjectElemArray<Elem> val(args[0]);
-    Elem result[V::lanes];
-    for (unsigned i = 0; i < V::lanes; i++)
-        result[i] = val[lanes[i]];
-
-    return StoreResult<V>(cx, args, result);
-}
-
-template<typename V>
-static bool
-Shuffle(JSContext* cx, unsigned argc, Value* vp)
-{
-    typedef typename V::Elem Elem;
-
-    CallArgs args = CallArgsFromVp(argc, vp);
-    if (args.length() != (V::lanes + 2) || !IsVectorObject<V>(args[0]) || !IsVectorObject<V>(args[1]))
-        return ErrorBadArgs(cx);
-
-    unsigned lanes[V::lanes];
-    for (unsigned i = 0; i < V::lanes; i++) {
-        if (!ArgumentToLaneIndex(cx, args[i + 2], 2 * V::lanes, &lanes[i]))
-            return false;
-    }
-
-    Elem result[V::lanes];
-    {
-        JS::AutoCheckCannotGC nogc(cx);
-        Elem* lhs = TypedObjectMemory<Elem*>(args[0], nogc);
-        Elem* rhs = TypedObjectMemory<Elem*>(args[1], nogc);
-
-        for (unsigned i = 0; i < V::lanes; i++) {
-            Elem* selectedInput = lanes[i] < V::lanes ? lhs : rhs;
-            result[i] = selectedInput[lanes[i] % V::lanes];
-        }
-    }
-
-    return StoreResult<V>(cx, args, result);
-}
-
-template<typename V, template<typename T> class Op>
-static bool
-BinaryScalar(JSContext* cx, unsigned argc, Value* vp)
-{
-    typedef typename V::Elem Elem;
-
-    CallArgs args = CallArgsFromVp(argc, vp);
-    if (args.length() != 2)
-        return ErrorBadArgs(cx);
-
-    if (!IsVectorObject<V>(args[0]))
-        return ErrorBadArgs(cx);
-
-    int32_t bits;
-    if (!ToInt32(cx, args[1], &bits))
-        return false;
-
-    TypedObjectElemArray<Elem> val(args[0]);
-    Elem result[V::lanes];
-    for (unsigned i = 0; i < V::lanes; i++)
-        result[i] = Op<Elem>::apply(val[i], bits);
-
-    return StoreResult<V>(cx, args, result);
-}
-
-template<typename In, template<typename C> class Op, typename Out>
-static bool
-CompareFunc(JSContext* cx, unsigned argc, Value* vp)
-{
-    typedef typename In::Elem InElem;
-    typedef typename Out::Elem OutElem;
-
-    CallArgs args = CallArgsFromVp(argc, vp);
-    if (args.length() != 2 || !IsVectorObject<In>(args[0]) || !IsVectorObject<In>(args[1]))
-        return ErrorBadArgs(cx);
-
-    OutElem result[Out::lanes];
-    TypedObjectElemArray<InElem> left(args[0]);
-    TypedObjectElemArray<InElem> right(args[1]);
-    for (unsigned i = 0; i < Out::lanes; i++) {
-        unsigned j = (i * In::lanes) / Out::lanes;
-        result[i] = Op<InElem>::apply(left[j], right[j]) ? -1 : 0;
-    }
-
-    return StoreResult<Out>(cx, args, result);
-}
-
-// This struct defines whether we should throw during a conversion attempt,
-// when trying to convert a value of type from From to the type To.  This
-// happens whenever a C++ conversion would have undefined behavior (and perhaps
-// be platform-dependent).
-template<typename From, typename To>
-struct ThrowOnConvert;
-
-struct NeverThrow
-{
-    static bool value(int32_t v) {
-        return false;
-    }
-};
-
-// While int32 to float conversions can be lossy, these conversions have
-// defined behavior in C++, so we don't need to care about them here. In practice,
-// this means round to nearest, tie with even (zero bit in significand).
-template<>
-struct ThrowOnConvert<int32_t, float> : public NeverThrow {};
-
-template<>
-struct ThrowOnConvert<uint32_t, float> : public NeverThrow {};
-
-// All int32 can be safely converted to doubles.
-template<>
-struct ThrowOnConvert<int32_t, double> : public NeverThrow {};
-
-template<>
-struct ThrowOnConvert<uint32_t, double> : public NeverThrow {};
-
-// All floats can be safely converted to doubles.
-template<>
-struct ThrowOnConvert<float, double> : public NeverThrow {};
-
-// Double to float conversion for inputs which aren't in the float range are
-// undefined behavior in C++, but they're defined in IEEE754.
-template<>
-struct ThrowOnConvert<double, float> : public NeverThrow {};
-
-// Float to integer conversions have undefined behavior if the float value
-// is out of the representable integer range (on x86, will yield the undefined
-// value pattern, namely 0x80000000; on arm, will clamp the input value), so
-// check this here.
-template<typename From, typename IntegerType>
-struct ThrowIfNotInRange
-{
-    static_assert(mozilla::IsIntegral<IntegerType>::value, "bad destination type");
-
-    static bool value(From v) {
-        // Truncate to integer value before the range check.
-        double d = trunc(double(v));
-        // Arrange relations so NaN returns true (i.e., it throws a RangeError).
-        return !(d >= double(mozilla::MinValue<IntegerType>::value) &&
-                 d <= double(mozilla::MaxValue<IntegerType>::value));
-    }
-};
-
-template<>
-struct ThrowOnConvert<double, int32_t> : public ThrowIfNotInRange<double, int32_t> {};
-
-template<>
-struct ThrowOnConvert<double, uint32_t> : public ThrowIfNotInRange<double, uint32_t> {};
-
-template<>
-struct ThrowOnConvert<float, int32_t> : public ThrowIfNotInRange<float, int32_t> {};
-
-template<>
-struct ThrowOnConvert<float, uint32_t> : public ThrowIfNotInRange<float, uint32_t> {};
-
-template<typename V, typename Vret>
-static bool
-FuncConvert(JSContext* cx, unsigned argc, Value* vp)
-{
-    typedef typename V::Elem Elem;
-    typedef typename Vret::Elem RetElem;
-
-    static_assert(!mozilla::IsSame<V,Vret>::value, "Can't convert SIMD type to itself");
-    static_assert(V::lanes == Vret::lanes, "Can only convert from same number of lanes");
-    static_assert(!mozilla::IsIntegral<Elem>::value || !mozilla::IsIntegral<RetElem>::value,
-                  "Cannot convert between integer SIMD types");
-
-    CallArgs args = CallArgsFromVp(argc, vp);
-    if (args.length() != 1 || !IsVectorObject<V>(args[0]))
-        return ErrorBadArgs(cx);
-
-    TypedObjectElemArray<Elem> val(args[0]);
-    RetElem result[Vret::lanes];
-    for (unsigned i = 0; i < V::lanes; i++) {
-        if (ThrowOnConvert<Elem, RetElem>::value(val[i])) {
-            JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_SIMD_FAILED_CONVERSION);
-            return false;
-        }
-        result[i] = ConvertScalar<RetElem>(val[i]);
-    }
-
-    return StoreResult<Vret>(cx, args, result);
-}
-
-template<typename V, typename Vret>
-static bool
-FuncConvertBits(JSContext* cx, unsigned argc, Value* vp)
-{
-    typedef typename V::Elem Elem;
-    typedef typename Vret::Elem RetElem;
-
-    static_assert(!mozilla::IsSame<V, Vret>::value, "Can't convert SIMD type to itself");
-    static_assert(V::lanes * sizeof(Elem) == Vret::lanes * sizeof(RetElem),
-                  "Can only bitcast from the same number of bits");
-
-    CallArgs args = CallArgsFromVp(argc, vp);
-    if (args.length() != 1 || !IsVectorObject<V>(args[0]))
-        return ErrorBadArgs(cx);
-
-    // While we could just pass the typedMem of args[0] as StoreResults' last
-    // argument, a GC could move the pointer to its memory in the meanwhile.
-    // For consistency with other SIMD functions, simply copy the input in a
-    // temporary array.
-    RetElem copy[Vret::lanes];
-    {
-        JS::AutoCheckCannotGC nogc(cx);
-        memcpy(copy, TypedObjectMemory<RetElem*>(args[0], nogc), Vret::lanes * sizeof(RetElem));
-    }
-    return StoreResult<Vret>(cx, args, copy);
-}
-
-template<typename Vret>
-static bool
-FuncSplat(JSContext* cx, unsigned argc, Value* vp)
-{
-    typedef typename Vret::Elem RetElem;
-
-    CallArgs args = CallArgsFromVp(argc, vp);
-    RetElem arg;
-    if (!Vret::Cast(cx, args.get(0), &arg))
-        return false;
-
-    RetElem result[Vret::lanes];
-    for (unsigned i = 0; i < Vret::lanes; i++)
-        result[i] = arg;
-    return StoreResult<Vret>(cx, args, result);
-}
-
-template<typename V>
-static bool
-Bool(JSContext* cx, unsigned argc, Value* vp)
-{
-    typedef typename V::Elem Elem;
-
-    CallArgs args = CallArgsFromVp(argc, vp);
-
-    Elem result[V::lanes];
-    for (unsigned i = 0; i < V::lanes; i++)
-        result[i] = ToBoolean(args.get(i)) ? -1 : 0;
-    return StoreResult<V>(cx, args, result);
-}
-
-template<typename V, typename MaskType>
-static bool
-SelectBits(JSContext* cx, unsigned argc, Value* vp)
-{
-    typedef typename V::Elem Elem;
-    typedef typename MaskType::Elem MaskTypeElem;
-
-    CallArgs args = CallArgsFromVp(argc, vp);
-    if (args.length() != 3 || !IsVectorObject<MaskType>(args[0]) ||
-        !IsVectorObject<V>(args[1]) || !IsVectorObject<V>(args[2]))
-    {
-        return ErrorBadArgs(cx);
-    }
-
-    TypedObjectElemArray<MaskTypeElem> val(args[0]);
-    TypedObjectElemArray<MaskTypeElem> tv(args[1]);
-    TypedObjectElemArray<MaskTypeElem> fv(args[2]);
-
-    MaskTypeElem tr[MaskType::lanes];
-    for (unsigned i = 0; i < MaskType::lanes; i++)
-        tr[i] = And<MaskTypeElem>::apply(val[i], tv[i]);
-
-    MaskTypeElem fr[MaskType::lanes];
-    for (unsigned i = 0; i < MaskType::lanes; i++)
-        fr[i] = And<MaskTypeElem>::apply(Not<MaskTypeElem>::apply(val[i]), fv[i]);
-
-    MaskTypeElem orInt[MaskType::lanes];
-    for (unsigned i = 0; i < MaskType::lanes; i++)
-        orInt[i] = Or<MaskTypeElem>::apply(tr[i], fr[i]);
-
-    Elem* result = reinterpret_cast<Elem*>(orInt);
-    return StoreResult<V>(cx, args, result);
-}
-
-template<typename V, typename MaskType>
-static bool
-Select(JSContext* cx, unsigned argc, Value* vp)
-{
-    typedef typename V::Elem Elem;
-    typedef typename MaskType::Elem MaskTypeElem;
-
-    CallArgs args = CallArgsFromVp(argc, vp);
-    if (args.length() != 3 || !IsVectorObject<MaskType>(args[0]) ||
-        !IsVectorObject<V>(args[1]) || !IsVectorObject<V>(args[2]))
-    {
-        return ErrorBadArgs(cx);
-    }
-
-    TypedObjectElemArray<MaskTypeElem> mask(args[0]);
-    TypedObjectElemArray<Elem> tv(args[1]);
-    TypedObjectElemArray<Elem> fv(args[2]);
-
-    Elem result[V::lanes];
-    for (unsigned i = 0; i < V::lanes; i++)
-        result[i] = mask[i] ? tv[i] : fv[i];
-
-    return StoreResult<V>(cx, args, result);
-}
-
-// Extract an integer lane index from a function argument.
-//
-// Register an exception and return false if the argument is not suitable.
-static bool
-ArgumentToLaneIndex(JSContext* cx, JS::HandleValue v, unsigned limit, unsigned* lane)
-{
-    uint64_t arg;
-    if (!NonStandardToIndex(cx, v, &arg))
-        return false;
-    if (arg >= limit)
-        return ErrorBadIndex(cx);
-
-    *lane = unsigned(arg);
-    return true;
-}
-
-// Look for arguments (ta, idx) where ta is a TypedArray and idx is a
-// non-negative integer.
-// Check that accessBytes can be accessed starting from index idx in the array.
-// Return the array handle in typedArray and idx converted to a byte offset in byteStart.
-static bool
-TypedArrayFromArgs(JSContext* cx, const CallArgs& args, uint32_t accessBytes,
-                   MutableHandleObject typedArray, size_t* byteStart)
-{
-    if (!args[0].isObject())
-        return ErrorBadArgs(cx);
-
-    JSObject& argobj = args[0].toObject();
-    if (!argobj.is<TypedArrayObject>())
-        return ErrorBadArgs(cx);
-
-    typedArray.set(&argobj);
-
-    uint64_t index;
-    if (!NonStandardToIndex(cx, args[1], &index))
-        return false;
-
-    // Do the range check in 64 bits even when size_t is 32 bits.
-    // This can't overflow because index <= 2^53.
-    uint64_t bytes = index * typedArray->as<TypedArrayObject>().bytesPerElement();
-    // Keep in sync with AsmJS OnOutOfBounds function.
-    if ((bytes + accessBytes) > typedArray->as<TypedArrayObject>().byteLength())
-        return ErrorBadIndex(cx);
-
-    *byteStart = bytes;
-
-    return true;
-}
-
-template<class V, unsigned NumElem>
-static bool
-Load(JSContext* cx, unsigned argc, Value* vp)
-{
-    typedef typename V::Elem Elem;
-
-    CallArgs args = CallArgsFromVp(argc, vp);
-    if (args.length() != 2)
-        return ErrorBadArgs(cx);
-
-    size_t byteStart;
-    RootedObject typedArray(cx);
-    if (!TypedArrayFromArgs(cx, args, sizeof(Elem) * NumElem, &typedArray, &byteStart))
-        return false;
-
-    Rooted<TypeDescr*> typeDescr(cx, GetTypeDescr<V>(cx));
-    if (!typeDescr)
-        return false;
-
-    Rooted<TypedObject*> result(cx, TypedObject::createZeroed(cx, typeDescr));
-    if (!result)
-        return false;
-
-    JS::AutoCheckCannotGC nogc(cx);
-    SharedMem<Elem*> src =
-        typedArray->as<TypedArrayObject>().viewDataEither().addBytes(byteStart).cast<Elem*>();
-    Elem* dst = reinterpret_cast<Elem*>(result->typedMem(nogc));
-    jit::AtomicOperations::podCopySafeWhenRacy(SharedMem<Elem*>::unshared(dst), src, NumElem);
-
-    args.rval().setObject(*result);
-    return true;
-}
-
-template<class V, unsigned NumElem>
-static bool
-Store(JSContext* cx, unsigned argc, Value* vp)
-{
-    typedef typename V::Elem Elem;
-
-    CallArgs args = CallArgsFromVp(argc, vp);
-    if (args.length() != 3)
-        return ErrorBadArgs(cx);
-
-    size_t byteStart;
-    RootedObject typedArray(cx);
-    if (!TypedArrayFromArgs(cx, args, sizeof(Elem) * NumElem, &typedArray, &byteStart))
-        return false;
-
-    if (!IsVectorObject<V>(args[2]))
-        return ErrorBadArgs(cx);
-
-    JS::AutoCheckCannotGC nogc(cx);
-    Elem* src = TypedObjectMemory<Elem*>(args[2], nogc);
-    SharedMem<Elem*> dst =
-        typedArray->as<TypedArrayObject>().viewDataEither().addBytes(byteStart).cast<Elem*>();
-    js::jit::AtomicOperations::podCopySafeWhenRacy(dst, SharedMem<Elem*>::unshared(src), NumElem);
-
-    args.rval().setObject(args[2].toObject());
-    return true;
-}
-
-#define DEFINE_SIMD_FLOAT32X4_FUNCTION(Name, Func, Operands)       \
-bool                                                               \
-js::simd_float32x4_##Name(JSContext* cx, unsigned argc, Value* vp) \
-{                                                                  \
-    return Func(cx, argc, vp);                                     \
-}
-FLOAT32X4_FUNCTION_LIST(DEFINE_SIMD_FLOAT32X4_FUNCTION)
-#undef DEFINE_SIMD_FLOAT32X4_FUNCTION
-
-#define DEFINE_SIMD_FLOAT64X2_FUNCTION(Name, Func, Operands)       \
-bool                                                               \
-js::simd_float64x2_##Name(JSContext* cx, unsigned argc, Value* vp) \
-{                                                                  \
-    return Func(cx, argc, vp);                                     \
-}
-FLOAT64X2_FUNCTION_LIST(DEFINE_SIMD_FLOAT64X2_FUNCTION)
-#undef DEFINE_SIMD_FLOAT64X2_FUNCTION
-
-#define DEFINE_SIMD_INT8X16_FUNCTION(Name, Func, Operands)         \
-bool                                                               \
-js::simd_int8x16_##Name(JSContext* cx, unsigned argc, Value* vp)   \
-{                                                                  \
-    return Func(cx, argc, vp);                                     \
-}
-INT8X16_FUNCTION_LIST(DEFINE_SIMD_INT8X16_FUNCTION)
-#undef DEFINE_SIMD_INT8X16_FUNCTION
-
-#define DEFINE_SIMD_INT16X8_FUNCTION(Name, Func, Operands)         \
-bool                                                               \
-js::simd_int16x8_##Name(JSContext* cx, unsigned argc, Value* vp)   \
-{                                                                  \
-    return Func(cx, argc, vp);                                     \
-}
-INT16X8_FUNCTION_LIST(DEFINE_SIMD_INT16X8_FUNCTION)
-#undef DEFINE_SIMD_INT16X8_FUNCTION
-
-#define DEFINE_SIMD_INT32X4_FUNCTION(Name, Func, Operands)         \
-bool                                                               \
-js::simd_int32x4_##Name(JSContext* cx, unsigned argc, Value* vp)   \
-{                                                                  \
-    return Func(cx, argc, vp);                                     \
-}
-INT32X4_FUNCTION_LIST(DEFINE_SIMD_INT32X4_FUNCTION)
-#undef DEFINE_SIMD_INT32X4_FUNCTION
-
-#define DEFINE_SIMD_UINT8X16_FUNCTION(Name, Func, Operands)        \
-bool                                                               \
-js::simd_uint8x16_##Name(JSContext* cx, unsigned argc, Value* vp)  \
-{                                                                  \
-    return Func(cx, argc, vp);                                     \
-}
-UINT8X16_FUNCTION_LIST(DEFINE_SIMD_UINT8X16_FUNCTION)
-#undef DEFINE_SIMD_UINT8X16_FUNCTION
-
-#define DEFINE_SIMD_UINT16X8_FUNCTION(Name, Func, Operands)        \
-bool                                                               \
-js::simd_uint16x8_##Name(JSContext* cx, unsigned argc, Value* vp)  \
-{                                                                  \
-    return Func(cx, argc, vp);                                     \
-}
-UINT16X8_FUNCTION_LIST(DEFINE_SIMD_UINT16X8_FUNCTION)
-#undef DEFINE_SIMD_UINT16X8_FUNCTION
-
-#define DEFINE_SIMD_UINT32X4_FUNCTION(Name, Func, Operands)        \
-bool                                                               \
-js::simd_uint32x4_##Name(JSContext* cx, unsigned argc, Value* vp)  \
-{                                                                  \
-    return Func(cx, argc, vp);                                     \
-}
-UINT32X4_FUNCTION_LIST(DEFINE_SIMD_UINT32X4_FUNCTION)
-#undef DEFINE_SIMD_UINT32X4_FUNCTION
-
-#define DEFINE_SIMD_BOOL8X16_FUNCTION(Name, Func, Operands)        \
-bool                                                               \
-js::simd_bool8x16_##Name(JSContext* cx, unsigned argc, Value* vp)  \
-{                                                                  \
-    return Func(cx, argc, vp);                                     \
-}
-
-BOOL8X16_FUNCTION_LIST(DEFINE_SIMD_BOOL8X16_FUNCTION)
-#undef DEFINE_SIMD_BOOL8X16_FUNCTION
-
-#define DEFINE_SIMD_BOOL16X8_FUNCTION(Name, Func, Operands)        \
-bool                                                               \
-js::simd_bool16x8_##Name(JSContext* cx, unsigned argc, Value* vp)  \
-{                                                                  \
-    return Func(cx, argc, vp);                                     \
-}
-BOOL16X8_FUNCTION_LIST(DEFINE_SIMD_BOOL16X8_FUNCTION)
-#undef DEFINE_SIMD_BOOL16X8_FUNCTION
-
-#define DEFINE_SIMD_BOOL32X4_FUNCTION(Name, Func, Operands)        \
-bool                                                               \
-js::simd_bool32x4_##Name(JSContext* cx, unsigned argc, Value* vp)  \
-{                                                                  \
-    return Func(cx, argc, vp);                                     \
-}
-BOOL32X4_FUNCTION_LIST(DEFINE_SIMD_BOOL32X4_FUNCTION)
-#undef DEFINE_SIMD_BOOL32X4_FUNCTION
-
-#define DEFINE_SIMD_BOOL64X2_FUNCTION(Name, Func, Operands)        \
-bool                                                               \
-js::simd_bool64x2_##Name(JSContext* cx, unsigned argc, Value* vp)  \
-{                                                                  \
-    return Func(cx, argc, vp);                                     \
-}
-BOOL64X2_FUNCTION_LIST(DEFINE_SIMD_BOOL64X2_FUNCTION)
-#undef DEFINE_SIMD_BOOL64X2_FUNCTION
deleted file mode 100644
--- a/js/src/builtin/SIMD.h
+++ /dev/null
@@ -1,298 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sts=4 et sw=4 tw=99:
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef builtin_SIMD_h
-#define builtin_SIMD_h
-
-#include "jsapi.h"
-#include "NamespaceImports.h"
-
-#include "builtin/SIMDConstants.h"
-#include "jit/IonTypes.h"
-#include "js/Conversions.h"
-
-/*
- * JS SIMD functions.
- * Spec matching polyfill:
- * https://github.com/tc39/ecmascript_simd/blob/master/src/ecmascript_simd.js
- */
-
-namespace js {
-
-class GlobalObject;
-
-// These classes implement the concept containing the following constraints:
-// - requires typename Elem: this is the scalar lane type, stored in each lane
-// of the SIMD vector.
-// - requires static const unsigned lanes: this is the number of lanes (length)
-// of the SIMD vector.
-// - requires static const SimdType type: this is the SimdType enum value
-// corresponding to the SIMD type.
-// - requires static bool Cast(JSContext*, JS::HandleValue, Elem*): casts a
-// given Value to the current scalar lane type and saves it in the Elem
-// out-param.
-// - requires static Value ToValue(Elem): returns a Value of the right type
-// containing the given value.
-//
-// This concept is used in the templates above to define the functions
-// associated to a given type and in their implementations, to avoid code
-// redundancy.
-
-struct Float32x4 {
-    typedef float Elem;
-    static const unsigned lanes = 4;
-    static const SimdType type = SimdType::Float32x4;
-    static MOZ_MUST_USE bool Cast(JSContext* cx, JS::HandleValue v, Elem* out) {
-        double d;
-        if (!ToNumber(cx, v, &d))
-            return false;
-        *out = float(d);
-        return true;
-    }
-    static Value ToValue(Elem value) {
-        return DoubleValue(JS::CanonicalizeNaN(value));
-    }
-};
-
-struct Float64x2 {
-    typedef double Elem;
-    static const unsigned lanes = 2;
-    static const SimdType type = SimdType::Float64x2;
-    static MOZ_MUST_USE bool Cast(JSContext* cx, JS::HandleValue v, Elem* out) {
-        return ToNumber(cx, v, out);
-    }
-    static Value ToValue(Elem value) {
-        return DoubleValue(JS::CanonicalizeNaN(value));
-    }
-};
-
-struct Int8x16 {
-    typedef int8_t Elem;
-    static const unsigned lanes = 16;
-    static const SimdType type = SimdType::Int8x16;
-    static MOZ_MUST_USE bool Cast(JSContext* cx, JS::HandleValue v, Elem* out) {
-        return ToInt8(cx, v, out);
-    }
-    static Value ToValue(Elem value) {
-        return NumberValue(value);
-    }
-};
-
-struct Int16x8 {
-    typedef int16_t Elem;
-    static const unsigned lanes = 8;
-    static const SimdType type = SimdType::Int16x8;
-    static MOZ_MUST_USE bool Cast(JSContext* cx, JS::HandleValue v, Elem* out) {
-        return ToInt16(cx, v, out);
-    }
-    static Value ToValue(Elem value) {
-        return NumberValue(value);
-    }
-};
-
-struct Int32x4 {
-    typedef int32_t Elem;
-    static const unsigned lanes = 4;
-    static const SimdType type = SimdType::Int32x4;
-    static MOZ_MUST_USE bool Cast(JSContext* cx, JS::HandleValue v, Elem* out) {
-        return ToInt32(cx, v, out);
-    }
-    static Value ToValue(Elem value) {
-        return NumberValue(value);
-    }
-};
-
-struct Uint8x16 {
-    typedef uint8_t Elem;
-    static const unsigned lanes = 16;
-    static const SimdType type = SimdType::Uint8x16;
-    static MOZ_MUST_USE bool Cast(JSContext* cx, JS::HandleValue v, Elem* out) {
-        return ToUint8(cx, v, out);
-    }
-    static Value ToValue(Elem value) {
-        return NumberValue(value);
-    }
-};
-
-struct Uint16x8 {
-    typedef uint16_t Elem;
-    static const unsigned lanes = 8;
-    static const SimdType type = SimdType::Uint16x8;
-    static MOZ_MUST_USE bool Cast(JSContext* cx, JS::HandleValue v, Elem* out) {
-        return ToUint16(cx, v, out);
-    }
-    static Value ToValue(Elem value) {
-        return NumberValue(value);
-    }
-};
-
-struct Uint32x4 {
-    typedef uint32_t Elem;
-    static const unsigned lanes = 4;
-    static const SimdType type = SimdType::Uint32x4;
-    static MOZ_MUST_USE bool Cast(JSContext* cx, JS::HandleValue v, Elem* out) {
-        return ToUint32(cx, v, out);
-    }
-    static Value ToValue(Elem value) {
-        return NumberValue(value);
-    }
-};
-
-struct Bool8x16 {
-    typedef int8_t Elem;
-    static const unsigned lanes = 16;
-    static const SimdType type = SimdType::Bool8x16;
-    static MOZ_MUST_USE bool Cast(JSContext* cx, JS::HandleValue v, Elem* out) {
-        *out = ToBoolean(v) ? -1 : 0;
-        return true;
-    }
-    static Value ToValue(Elem value) {
-        return BooleanValue(value);
-    }
-};
-
-struct Bool16x8 {
-    typedef int16_t Elem;
-    static const unsigned lanes = 8;
-    static const SimdType type = SimdType::Bool16x8;
-    static MOZ_MUST_USE bool Cast(JSContext* cx, JS::HandleValue v, Elem* out) {
-        *out = ToBoolean(v) ? -1 : 0;
-        return true;
-    }
-    static Value ToValue(Elem value) {
-        return BooleanValue(value);
-    }
-};
-
-struct Bool32x4 {
-    typedef int32_t Elem;
-    static const unsigned lanes = 4;
-    static const SimdType type = SimdType::Bool32x4;
-    static MOZ_MUST_USE bool Cast(JSContext* cx, JS::HandleValue v, Elem* out) {
-        *out = ToBoolean(v) ? -1 : 0;
-        return true;
-    }
-    static Value ToValue(Elem value) {
-        return BooleanValue(value);
-    }
-};
-
-struct Bool64x2 {
-    typedef int64_t Elem;
-    static const unsigned lanes = 2;
-    static const SimdType type = SimdType::Bool64x2;
-    static MOZ_MUST_USE bool Cast(JSContext* cx, JS::HandleValue v, Elem* out) {
-        *out = ToBoolean(v) ? -1 : 0;
-        return true;
-    }
-    static Value ToValue(Elem value) {
-        return BooleanValue(value);
-    }
-};
-
-// Get the well known name of the SIMD.* object corresponding to type.
-PropertyName* SimdTypeToName(const JSAtomState& atoms, SimdType type);
-
-// Check if name is the well known name of a SIMD type.
-// Returns true and sets *type iff name is known.
-bool IsSimdTypeName(const JSAtomState& atoms, const PropertyName* name, SimdType* type);
-
-const char* SimdTypeToString(SimdType type);
-
-template<typename V>
-JSObject* CreateSimd(JSContext* cx, const typename V::Elem* data);
-
-template<typename V>
-bool IsVectorObject(HandleValue v);
-
-template<typename V>
-MOZ_MUST_USE bool ToSimdConstant(JSContext* cx, HandleValue v, jit::SimdConstant* out);
-
-JSObject*
-InitSimdClass(JSContext* cx, Handle<GlobalObject*> global);
-
-namespace jit {
-
-extern const JSJitInfo JitInfo_SimdInt32x4_extractLane;
-extern const JSJitInfo JitInfo_SimdFloat32x4_extractLane;
-
-} // namespace jit
-
-#define DECLARE_SIMD_FLOAT32X4_FUNCTION(Name, Func, Operands)   \
-extern MOZ_MUST_USE bool                                        \
-simd_float32x4_##Name(JSContext* cx, unsigned argc, Value* vp);
-FLOAT32X4_FUNCTION_LIST(DECLARE_SIMD_FLOAT32X4_FUNCTION)
-#undef DECLARE_SIMD_FLOAT32X4_FUNCTION
-
-#define DECLARE_SIMD_FLOAT64X2_FUNCTION(Name, Func, Operands)   \
-extern MOZ_MUST_USE bool                                        \
-simd_float64x2_##Name(JSContext* cx, unsigned argc, Value* vp);
-FLOAT64X2_FUNCTION_LIST(DECLARE_SIMD_FLOAT64X2_FUNCTION)
-#undef DECLARE_SIMD_FLOAT64X2_FUNCTION
-
-#define DECLARE_SIMD_INT8X16_FUNCTION(Name, Func, Operands)     \
-extern MOZ_MUST_USE bool                                        \
-simd_int8x16_##Name(JSContext* cx, unsigned argc, Value* vp);
-INT8X16_FUNCTION_LIST(DECLARE_SIMD_INT8X16_FUNCTION)
-#undef DECLARE_SIMD_INT8X16_FUNCTION
-
-#define DECLARE_SIMD_INT16X8_FUNCTION(Name, Func, Operands)     \
-extern MOZ_MUST_USE bool                                        \
-simd_int16x8_##Name(JSContext* cx, unsigned argc, Value* vp);
-INT16X8_FUNCTION_LIST(DECLARE_SIMD_INT16X8_FUNCTION)
-#undef DECLARE_SIMD_INT16X8_FUNCTION
-
-#define DECLARE_SIMD_INT32X4_FUNCTION(Name, Func, Operands)     \
-extern MOZ_MUST_USE bool                                        \
-simd_int32x4_##Name(JSContext* cx, unsigned argc, Value* vp);
-INT32X4_FUNCTION_LIST(DECLARE_SIMD_INT32X4_FUNCTION)
-#undef DECLARE_SIMD_INT32X4_FUNCTION
-
-#define DECLARE_SIMD_UINT8X16_FUNCTION(Name, Func, Operands)    \
-extern MOZ_MUST_USE bool                                        \
-simd_uint8x16_##Name(JSContext* cx, unsigned argc, Value* vp);
-UINT8X16_FUNCTION_LIST(DECLARE_SIMD_UINT8X16_FUNCTION)
-#undef DECLARE_SIMD_UINT8X16_FUNCTION
-
-#define DECLARE_SIMD_UINT16X8_FUNCTION(Name, Func, Operands)    \
-extern MOZ_MUST_USE bool                                        \
-simd_uint16x8_##Name(JSContext* cx, unsigned argc, Value* vp);
-UINT16X8_FUNCTION_LIST(DECLARE_SIMD_UINT16X8_FUNCTION)
-#undef DECLARE_SIMD_UINT16X8_FUNCTION
-
-#define DECLARE_SIMD_UINT32X4_FUNCTION(Name, Func, Operands)    \
-extern MOZ_MUST_USE bool                                        \
-simd_uint32x4_##Name(JSContext* cx, unsigned argc, Value* vp);
-UINT32X4_FUNCTION_LIST(DECLARE_SIMD_UINT32X4_FUNCTION)
-#undef DECLARE_SIMD_UINT32X4_FUNCTION
-
-#define DECLARE_SIMD_BOOL8X16_FUNCTION(Name, Func, Operands)    \
-extern MOZ_MUST_USE bool                                        \
-simd_bool8x16_##Name(JSContext* cx, unsigned argc, Value* vp);
-BOOL8X16_FUNCTION_LIST(DECLARE_SIMD_BOOL8X16_FUNCTION)
-#undef DECLARE_SIMD_BOOL8X16_FUNCTION
-
-#define DECLARE_SIMD_BOOL16X8_FUNCTION(Name, Func, Operands)    \
-extern MOZ_MUST_USE bool                                        \
-simd_bool16x8_##Name(JSContext* cx, unsigned argc, Value* vp);
-BOOL16X8_FUNCTION_LIST(DECLARE_SIMD_BOOL16X8_FUNCTION)
-#undef DECLARE_SIMD_BOOL16X8_FUNCTION
-
-#define DECLARE_SIMD_BOOL32X4_FUNCTION(Name, Func, Operands)    \
-extern MOZ_MUST_USE bool                                        \
-simd_bool32x4_##Name(JSContext* cx, unsigned argc, Value* vp);
-BOOL32X4_FUNCTION_LIST(DECLARE_SIMD_BOOL32X4_FUNCTION)
-#undef DECLARE_SIMD_BOOL32X4_FUNCTION
-
-#define DECLARE_SIMD_BOOL64X2_FUNCTION(Name, Func, Operands)    \
-extern MOZ_MUST_USE bool                                        \
-simd_bool64x2_##Name(JSContext* cx, unsigned argc, Value* vp);
-BOOL64X2_FUNCTION_LIST(DECLARE_SIMD_BOOL64X2_FUNCTION)
-#undef DECLARE_SIMD_BOOL64X2_FUNCTION
-
-}  /* namespace js */
-
-#endif /* builtin_SIMD_h */
deleted file mode 100644
--- a/js/src/builtin/SIMDConstants.h
+++ /dev/null
@@ -1,941 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sts=4 et sw=4 tw=99:
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef builtin_SIMDConstants_h
-#define builtin_SIMDConstants_h
-
-#include "mozilla/Assertions.h"
-
-#include "builtin/TypedObjectConstants.h"
-
-// Bool8x16.
-#define BOOL8X16_UNARY_FUNCTION_LIST(V)                                               \
-  V(not, (UnaryFunc<Bool8x16, LogicalNot, Bool8x16>), 1)                              \
-  V(check, (UnaryFunc<Bool8x16, Identity, Bool8x16>), 1)                              \
-  V(splat, (FuncSplat<Bool8x16>), 1)                                                  \
-  V(allTrue, (AllTrue<Bool8x16>), 1)                                                  \
-  V(anyTrue, (AnyTrue<Bool8x16>), 1)
-
-#define BOOL8X16_BINARY_FUNCTION_LIST(V)                                              \
-  V(extractLane, (ExtractLane<Bool8x16>), 2)                                          \
-  V(and, (BinaryFunc<Bool8x16, And, Bool8x16>), 2)                                    \
-  V(or, (BinaryFunc<Bool8x16, Or, Bool8x16>), 2)                                      \
-  V(xor, (BinaryFunc<Bool8x16, Xor, Bool8x16>), 2)                                    \
-
-#define BOOL8X16_TERNARY_FUNCTION_LIST(V)                                             \
-  V(replaceLane, (ReplaceLane<Bool8x16>), 3)
-
-#define BOOL8X16_FUNCTION_LIST(V)                                                     \
-  BOOL8X16_UNARY_FUNCTION_LIST(V)                                                     \
-  BOOL8X16_BINARY_FUNCTION_LIST(V)                                                    \
-  BOOL8X16_TERNARY_FUNCTION_LIST(V)
-
-// Bool 16x8.
-#define BOOL16X8_UNARY_FUNCTION_LIST(V)                                               \
-  V(not, (UnaryFunc<Bool16x8, LogicalNot, Bool16x8>), 1)                              \
-  V(check, (UnaryFunc<Bool16x8, Identity, Bool16x8>), 1)                              \
-  V(splat, (FuncSplat<Bool16x8>), 1)                                                  \
-  V(allTrue, (AllTrue<Bool16x8>), 1)                                                  \
-  V(anyTrue, (AnyTrue<Bool16x8>), 1)
-
-#define BOOL16X8_BINARY_FUNCTION_LIST(V)                                              \
-  V(extractLane, (ExtractLane<Bool16x8>), 2)                                          \
-  V(and, (BinaryFunc<Bool16x8, And, Bool16x8>), 2)                                    \
-  V(or, (BinaryFunc<Bool16x8, Or, Bool16x8>), 2)                                      \
-  V(xor, (BinaryFunc<Bool16x8, Xor, Bool16x8>), 2)                                    \
-
-#define BOOL16X8_TERNARY_FUNCTION_LIST(V)                                             \
-  V(replaceLane, (ReplaceLane<Bool16x8>), 3)
-
-#define BOOL16X8_FUNCTION_LIST(V)                                                     \
-  BOOL16X8_UNARY_FUNCTION_LIST(V)                                                     \
-  BOOL16X8_BINARY_FUNCTION_LIST(V)                                                    \
-  BOOL16X8_TERNARY_FUNCTION_LIST(V)
-
-// Bool32x4.
-#define BOOL32X4_UNARY_FUNCTION_LIST(V)                                               \
-  V(not, (UnaryFunc<Bool32x4, LogicalNot, Bool32x4>), 1)                              \
-  V(check, (UnaryFunc<Bool32x4, Identity, Bool32x4>), 1)                              \
-  V(splat, (FuncSplat<Bool32x4>), 1)                                                  \
-  V(allTrue, (AllTrue<Bool32x4>), 1)                                                  \
-  V(anyTrue, (AnyTrue<Bool32x4>), 1)
-
-#define BOOL32X4_BINARY_FUNCTION_LIST(V)                                              \
-  V(extractLane, (ExtractLane<Bool32x4>), 2)                                          \
-  V(and, (BinaryFunc<Bool32x4, And, Bool32x4>), 2)                                    \
-  V(or, (BinaryFunc<Bool32x4, Or, Bool32x4>), 2)                                      \
-  V(xor, (BinaryFunc<Bool32x4, Xor, Bool32x4>), 2)                                    \
-
-#define BOOL32X4_TERNARY_FUNCTION_LIST(V)                                             \
-  V(replaceLane, (ReplaceLane<Bool32x4>), 3)
-
-#define BOOL32X4_FUNCTION_LIST(V)                                                     \
-  BOOL32X4_UNARY_FUNCTION_LIST(V)                                                     \
-  BOOL32X4_BINARY_FUNCTION_LIST(V)                                                    \
-  BOOL32X4_TERNARY_FUNCTION_LIST(V)
-
-// Bool64x2.
-#define BOOL64X2_UNARY_FUNCTION_LIST(V)                                               \
-  V(not, (UnaryFunc<Bool64x2, LogicalNot, Bool64x2>), 1)                              \
-  V(check, (UnaryFunc<Bool64x2, Identity, Bool64x2>), 1)                              \
-  V(splat, (FuncSplat<Bool64x2>), 1)                                                  \
-  V(allTrue, (AllTrue<Bool64x2>), 1)                                                  \
-  V(anyTrue, (AnyTrue<Bool64x2>), 1)
-
-#define BOOL64X2_BINARY_FUNCTION_LIST(V)                                              \
-  V(extractLane, (ExtractLane<Bool64x2>), 2)                                          \
-  V(and, (BinaryFunc<Bool64x2, And, Bool64x2>), 2)                                    \
-  V(or, (BinaryFunc<Bool64x2, Or, Bool64x2>), 2)                                      \
-  V(xor, (BinaryFunc<Bool64x2, Xor, Bool64x2>), 2)                                    \
-
-#define BOOL64X2_TERNARY_FUNCTION_LIST(V)                                             \
-  V(replaceLane, (ReplaceLane<Bool64x2>), 3)
-
-#define BOOL64X2_FUNCTION_LIST(V)                                                     \
-  BOOL64X2_UNARY_FUNCTION_LIST(V)                                                     \
-  BOOL64X2_BINARY_FUNCTION_LIST(V)                                                    \
-  BOOL64X2_TERNARY_FUNCTION_LIST(V)
-
-// Float32x4.
-#define FLOAT32X4_UNARY_FUNCTION_LIST(V)                                              \
-  V(abs, (UnaryFunc<Float32x4, Abs, Float32x4>), 1)                                   \
-  V(check, (UnaryFunc<Float32x4, Identity, Float32x4>), 1)                            \
-  V(fromFloat64x2Bits, (FuncConvertBits<Float64x2, Float32x4>), 1)                    \
-  V(fromInt8x16Bits,   (FuncConvertBits<Int8x16,   Float32x4>), 1)                    \
-  V(fromInt16x8Bits,   (FuncConvertBits<Int16x8,   Float32x4>), 1)                    \
-  V(fromInt32x4,       (FuncConvert<Int32x4,       Float32x4>), 1)                    \
-  V(fromInt32x4Bits,   (FuncConvertBits<Int32x4,   Float32x4>), 1)                    \
-  V(fromUint8x16Bits,  (FuncConvertBits<Uint8x16,  Float32x4>), 1)                    \
-  V(fromUint16x8Bits,  (FuncConvertBits<Uint16x8,  Float32x4>), 1)                    \
-  V(fromUint32x4,      (FuncConvert<Uint32x4,      Float32x4>), 1)                    \
-  V(fromUint32x4Bits,  (FuncConvertBits<Uint32x4,  Float32x4>), 1)                    \
-  V(neg, (UnaryFunc<Float32x4, Neg, Float32x4>), 1)                                   \
-  V(reciprocalApproximation, (UnaryFunc<Float32x4, RecApprox, Float32x4>), 1)         \
-  V(reciprocalSqrtApproximation, (UnaryFunc<Float32x4, RecSqrtApprox, Float32x4>), 1) \
-  V(splat, (FuncSplat<Float32x4>), 1)                                                 \
-  V(sqrt, (UnaryFunc<Float32x4, Sqrt, Float32x4>), 1)
-
-#define FLOAT32X4_BINARY_FUNCTION_LIST(V)                                             \
-  V(add, (BinaryFunc<Float32x4, Add, Float32x4>), 2)                                  \
-  V(div, (BinaryFunc<Float32x4, Div, Float32x4>), 2)                                  \
-  V(equal, (CompareFunc<Float32x4, Equal, Bool32x4>), 2)                              \
-  V(extractLane, (ExtractLane<Float32x4>), 2)                                         \
-  V(greaterThan, (CompareFunc<Float32x4, GreaterThan, Bool32x4>), 2)                  \
-  V(greaterThanOrEqual, (CompareFunc<Float32x4, GreaterThanOrEqual, Bool32x4>), 2)    \
-  V(lessThan, (CompareFunc<Float32x4, LessThan, Bool32x4>), 2)                        \
-  V(lessThanOrEqual, (CompareFunc<Float32x4, LessThanOrEqual, Bool32x4>), 2)          \
-  V(load,  (Load<Float32x4, 4>), 2)                                                   \
-  V(load3, (Load<Float32x4, 3>), 2)                                                   \
-  V(load2, (Load<Float32x4, 2>), 2)                                                   \
-  V(load1, (Load<Float32x4, 1>), 2)                                                   \
-  V(max, (BinaryFunc<Float32x4, Maximum, Float32x4>), 2)                              \
-  V(maxNum, (BinaryFunc<Float32x4, MaxNum, Float32x4>), 2)                            \
-  V(min, (BinaryFunc<Float32x4, Minimum, Float32x4>), 2)                              \
-  V(minNum, (BinaryFunc<Float32x4, MinNum, Float32x4>), 2)                            \
-  V(mul, (BinaryFunc<Float32x4, Mul, Float32x4>), 2)                                  \
-  V(notEqual, (CompareFunc<Float32x4, NotEqual, Bool32x4>), 2)                        \
-  V(sub, (BinaryFunc<Float32x4, Sub, Float32x4>), 2)
-
-#define FLOAT32X4_TERNARY_FUNCTION_LIST(V)                                            \
-  V(replaceLane, (ReplaceLane<Float32x4>), 3)                                         \
-  V(select, (Select<Float32x4, Bool32x4>), 3)                                         \
-  V(store,  (Store<Float32x4, 4>), 3)                                                 \
-  V(store3, (Store<Float32x4, 3>), 3)                                                 \
-  V(store2, (Store<Float32x4, 2>), 3)                                                 \
-  V(store1, (Store<Float32x4, 1>), 3)
-
-#define FLOAT32X4_SHUFFLE_FUNCTION_LIST(V)                                            \
-  V(swizzle, Swizzle<Float32x4>, 5)                                                   \
-  V(shuffle, Shuffle<Float32x4>, 6)
-
-#define FLOAT32X4_FUNCTION_LIST(V)                                                    \
-  FLOAT32X4_UNARY_FUNCTION_LIST(V)                                                    \
-  FLOAT32X4_BINARY_FUNCTION_LIST(V)                                                   \
-  FLOAT32X4_TERNARY_FUNCTION_LIST(V)                                                  \
-  FLOAT32X4_SHUFFLE_FUNCTION_LIST(V)
-
-// Float64x2.
-#define FLOAT64X2_UNARY_FUNCTION_LIST(V)                                              \
-  V(abs, (UnaryFunc<Float64x2, Abs, Float64x2>), 1)                                   \
-  V(check, (UnaryFunc<Float64x2, Identity, Float64x2>), 1)                            \
-  V(fromFloat32x4Bits, (FuncConvertBits<Float32x4, Float64x2>), 1)                    \
-  V(fromInt8x16Bits,   (FuncConvertBits<Int8x16,   Float64x2>), 1)                    \
-  V(fromInt16x8Bits,   (FuncConvertBits<Int16x8,   Float64x2>), 1)                    \
-  V(fromInt32x4Bits,   (FuncConvertBits<Int32x4,   Float64x2>), 1)                    \
-  V(fromUint8x16Bits,  (FuncConvertBits<Uint8x16,  Float64x2>), 1)                    \
-  V(fromUint16x8Bits,  (FuncConvertBits<Uint16x8,  Float64x2>), 1)                    \
-  V(fromUint32x4Bits,  (FuncConvertBits<Uint32x4,  Float64x2>), 1)                    \
-  V(neg, (UnaryFunc<Float64x2, Neg, Float64x2>), 1)                                   \
-  V(reciprocalApproximation, (UnaryFunc<Float64x2, RecApprox, Float64x2>), 1)         \
-  V(reciprocalSqrtApproximation, (UnaryFunc<Float64x2, RecSqrtApprox, Float64x2>), 1) \
-  V(splat, (FuncSplat<Float64x2>), 1)                                                 \
-  V(sqrt, (UnaryFunc<Float64x2, Sqrt, Float64x2>), 1)
-
-#define FLOAT64X2_BINARY_FUNCTION_LIST(V)                                             \
-  V(add, (BinaryFunc<Float64x2, Add, Float64x2>), 2)                                  \
-  V(div, (BinaryFunc<Float64x2, Div, Float64x2>), 2)                                  \
-  V(equal, (CompareFunc<Float64x2, Equal, Bool64x2>), 2)                              \
-  V(extractLane, (ExtractLane<Float64x2>), 2)                                         \
-  V(greaterThan, (CompareFunc<Float64x2, GreaterThan, Bool64x2>), 2)                  \
-  V(greaterThanOrEqual, (CompareFunc<Float64x2, GreaterThanOrEqual, Bool64x2>), 2)    \
-  V(lessThan, (CompareFunc<Float64x2, LessThan, Bool64x2>), 2)                        \
-  V(lessThanOrEqual, (CompareFunc<Float64x2, LessThanOrEqual, Bool64x2>), 2)          \
-  V(load,  (Load<Float64x2, 2>), 2)                                                   \
-  V(load1, (Load<Float64x2, 1>), 2)                                                   \
-  V(max, (BinaryFunc<Float64x2, Maximum, Float64x2>), 2)                              \
-  V(maxNum, (BinaryFunc<Float64x2, MaxNum, Float64x2>), 2)                            \
-  V(min, (BinaryFunc<Float64x2, Minimum, Float64x2>), 2)                              \
-  V(minNum, (BinaryFunc<Float64x2, MinNum, Float64x2>), 2)                            \
-  V(mul, (BinaryFunc<Float64x2, Mul, Float64x2>), 2)                                  \
-  V(notEqual, (CompareFunc<Float64x2, NotEqual, Bool64x2>), 2)                        \
-  V(sub, (BinaryFunc<Float64x2, Sub, Float64x2>), 2)
-
-#define FLOAT64X2_TERNARY_FUNCTION_LIST(V)                                            \
-  V(replaceLane, (ReplaceLane<Float64x2>), 3)                                         \
-  V(select, (Select<Float64x2, Bool64x2>), 3)                                         \
-  V(store,  (Store<Float64x2, 2>), 3)                                                 \
-  V(store1, (Store<Float64x2, 1>), 3)
-
-#define FLOAT64X2_SHUFFLE_FUNCTION_LIST(V)                                            \
-  V(swizzle, Swizzle<Float64x2>, 3)                                                   \
-  V(shuffle, Shuffle<Float64x2>, 4)
-
-#define FLOAT64X2_FUNCTION_LIST(V)                                                    \
-  FLOAT64X2_UNARY_FUNCTION_LIST(V)                                                    \
-  FLOAT64X2_BINARY_FUNCTION_LIST(V)                                                   \
-  FLOAT64X2_TERNARY_FUNCTION_LIST(V)                                                  \
-  FLOAT64X2_SHUFFLE_FUNCTION_LIST(V)
-
-// Int8x16.
-#define INT8X16_UNARY_FUNCTION_LIST(V)                                                \
-  V(check, (UnaryFunc<Int8x16, Identity, Int8x16>), 1)                                \
-  V(fromFloat32x4Bits, (FuncConvertBits<Float32x4, Int8x16>), 1)                      \
-  V(fromFloat64x2Bits, (FuncConvertBits<Float64x2, Int8x16>), 1)                      \
-  V(fromInt16x8Bits,   (FuncConvertBits<Int16x8,   Int8x16>), 1)                      \
-  V(fromInt32x4Bits,   (FuncConvertBits<Int32x4,   Int8x16>), 1)                      \
-  V(fromUint8x16Bits,  (FuncConvertBits<Uint8x16,  Int8x16>), 1)                      \
-  V(fromUint16x8Bits,  (FuncConvertBits<Uint16x8,  Int8x16>), 1)                      \
-  V(fromUint32x4Bits,  (FuncConvertBits<Uint32x4,  Int8x16>), 1)                      \
-  V(neg, (UnaryFunc<Int8x16, Neg, Int8x16>), 1)                                       \
-  V(not, (UnaryFunc<Int8x16, Not, Int8x16>), 1)                                       \
-  V(splat, (FuncSplat<Int8x16>), 1)
-
-#define INT8X16_BINARY_FUNCTION_LIST(V)                                               \
-  V(add, (BinaryFunc<Int8x16, Add, Int8x16>), 2)                                      \
-  V(addSaturate, (BinaryFunc<Int8x16, AddSaturate, Int8x16>), 2)                      \
-  V(and, (BinaryFunc<Int8x16, And, Int8x16>), 2)                                      \
-  V(equal, (CompareFunc<Int8x16, Equal, Bool8x16>), 2)                                \
-  V(extractLane, (ExtractLane<Int8x16>), 2)                                           \
-  V(greaterThan, (CompareFunc<Int8x16, GreaterThan, Bool8x16>), 2)                    \
-  V(greaterThanOrEqual, (CompareFunc<Int8x16, GreaterThanOrEqual, Bool8x16>), 2)      \
-  V(lessThan, (CompareFunc<Int8x16, LessThan, Bool8x16>), 2)                          \
-  V(lessThanOrEqual, (CompareFunc<Int8x16, LessThanOrEqual, Bool8x16>), 2)            \
-  V(load, (Load<Int8x16, 16>), 2)                                                     \
-  V(mul, (BinaryFunc<Int8x16, Mul, Int8x16>), 2)                                      \
-  V(notEqual, (CompareFunc<Int8x16, NotEqual, Bool8x16>), 2)                          \
-  V(or, (BinaryFunc<Int8x16, Or, Int8x16>), 2)                                        \
-  V(sub, (BinaryFunc<Int8x16, Sub, Int8x16>), 2)                                      \
-  V(subSaturate, (BinaryFunc<Int8x16, SubSaturate, Int8x16>), 2)                      \
-  V(shiftLeftByScalar, (BinaryScalar<Int8x16, ShiftLeft>), 2)                         \
-  V(shiftRightByScalar, (BinaryScalar<Int8x16, ShiftRightArithmetic>), 2)             \
-  V(xor, (BinaryFunc<Int8x16, Xor, Int8x16>), 2)
-
-#define INT8X16_TERNARY_FUNCTION_LIST(V)                                              \
-  V(replaceLane, (ReplaceLane<Int8x16>), 3)                                           \
-  V(select, (Select<Int8x16, Bool8x16>), 3)                                           \
-  V(store, (Store<Int8x16, 16>), 3)
-
-#define INT8X16_SHUFFLE_FUNCTION_LIST(V)                                              \
-  V(swizzle, Swizzle<Int8x16>, 17)                                                    \
-  V(shuffle, Shuffle<Int8x16>, 18)
-
-#define INT8X16_FUNCTION_LIST(V)                                                      \
-  INT8X16_UNARY_FUNCTION_LIST(V)                                                      \
-  INT8X16_BINARY_FUNCTION_LIST(V)                                                     \
-  INT8X16_TERNARY_FUNCTION_LIST(V)                                                    \
-  INT8X16_SHUFFLE_FUNCTION_LIST(V)
-
-// Uint8x16.
-#define UINT8X16_UNARY_FUNCTION_LIST(V)                                               \
-  V(check, (UnaryFunc<Uint8x16, Identity, Uint8x16>), 1)                              \
-  V(fromFloat32x4Bits, (FuncConvertBits<Float32x4, Uint8x16>), 1)                     \
-  V(fromFloat64x2Bits, (FuncConvertBits<Float64x2, Uint8x16>), 1)                     \
-  V(fromInt8x16Bits,   (FuncConvertBits<Int8x16,   Uint8x16>), 1)                     \
-  V(fromInt16x8Bits,   (FuncConvertBits<Int16x8,   Uint8x16>), 1)                     \
-  V(fromInt32x4Bits,   (FuncConvertBits<Int32x4,   Uint8x16>), 1)                     \
-  V(fromUint16x8Bits,  (FuncConvertBits<Uint16x8,  Uint8x16>), 1)                     \
-  V(fromUint32x4Bits,  (FuncConvertBits<Uint32x4,  Uint8x16>), 1)                     \
-  V(neg, (UnaryFunc<Uint8x16, Neg, Uint8x16>), 1)                                     \
-  V(not, (UnaryFunc<Uint8x16, Not, Uint8x16>), 1)                                     \
-  V(splat, (FuncSplat<Uint8x16>), 1)
-
-#define UINT8X16_BINARY_FUNCTION_LIST(V)                                              \
-  V(add, (BinaryFunc<Uint8x16, Add, Uint8x16>), 2)                                    \
-  V(addSaturate, (BinaryFunc<Uint8x16, AddSaturate, Uint8x16>), 2)                    \
-  V(and, (BinaryFunc<Uint8x16, And, Uint8x16>), 2)                                    \
-  V(equal, (CompareFunc<Uint8x16, Equal, Bool8x16>), 2)                               \
-  V(extractLane, (ExtractLane<Uint8x16>), 2)                                          \
-  V(greaterThan, (CompareFunc<Uint8x16, GreaterThan, Bool8x16>), 2)                   \
-  V(greaterThanOrEqual, (CompareFunc<Uint8x16, GreaterThanOrEqual, Bool8x16>), 2)     \
-  V(lessThan, (CompareFunc<Uint8x16, LessThan, Bool8x16>), 2)                         \
-  V(lessThanOrEqual, (CompareFunc<Uint8x16, LessThanOrEqual, Bool8x16>), 2)           \
-  V(load, (Load<Uint8x16, 16>), 2)                                                    \
-  V(mul, (BinaryFunc<Uint8x16, Mul, Uint8x16>), 2)                                    \
-  V(notEqual, (CompareFunc<Uint8x16, NotEqual, Bool8x16>), 2)                         \
-  V(or, (BinaryFunc<Uint8x16, Or, Uint8x16>), 2)                                      \
-  V(sub, (BinaryFunc<Uint8x16, Sub, Uint8x16>), 2)                                    \
-  V(subSaturate, (BinaryFunc<Uint8x16, SubSaturate, Uint8x16>), 2)                    \
-  V(shiftLeftByScalar, (BinaryScalar<Uint8x16, ShiftLeft>), 2)                        \
-  V(shiftRightByScalar, (BinaryScalar<Uint8x16, ShiftRightLogical>), 2)               \
-  V(xor, (BinaryFunc<Uint8x16, Xor, Uint8x16>), 2)
-
-#define UINT8X16_TERNARY_FUNCTION_LIST(V)                                             \
-  V(replaceLane, (ReplaceLane<Uint8x16>), 3)                                          \
-  V(select, (Select<Uint8x16, Bool8x16>), 3)                                          \
-  V(store, (Store<Uint8x16, 16>), 3)
-
-#define UINT8X16_SHUFFLE_FUNCTION_LIST(V)                                             \
-  V(swizzle, Swizzle<Uint8x16>, 17)                                                   \
-  V(shuffle, Shuffle<Uint8x16>, 18)
-
-#define UINT8X16_FUNCTION_LIST(V)                                                     \
-  UINT8X16_UNARY_FUNCTION_LIST(V)                                                     \
-  UINT8X16_BINARY_FUNCTION_LIST(V)                                                    \
-  UINT8X16_TERNARY_FUNCTION_LIST(V)                                                   \
-  UINT8X16_SHUFFLE_FUNCTION_LIST(V)
-
-// Int16x8.
-#define INT16X8_UNARY_FUNCTION_LIST(V)                                                \
-  V(check, (UnaryFunc<Int16x8, Identity, Int16x8>), 1)                                \
-  V(fromFloat32x4Bits, (FuncConvertBits<Float32x4, Int16x8>), 1)                      \
-  V(fromFloat64x2Bits, (FuncConvertBits<Float64x2, Int16x8>), 1)                      \
-  V(fromInt8x16Bits,   (FuncConvertBits<Int8x16,   Int16x8>), 1)                      \
-  V(fromInt32x4Bits,   (FuncConvertBits<Int32x4,   Int16x8>), 1)                      \
-  V(fromUint8x16Bits,  (FuncConvertBits<Uint8x16,  Int16x8>), 1)                      \
-  V(fromUint16x8Bits,  (FuncConvertBits<Uint16x8,  Int16x8>), 1)                      \
-  V(fromUint32x4Bits,  (FuncConvertBits<Uint32x4,  Int16x8>), 1)                      \
-  V(neg, (UnaryFunc<Int16x8, Neg, Int16x8>), 1)                                       \
-  V(not, (UnaryFunc<Int16x8, Not, Int16x8>), 1)                                       \
-  V(splat, (FuncSplat<Int16x8>), 1)
-
-#define INT16X8_BINARY_FUNCTION_LIST(V)                                               \
-  V(add, (BinaryFunc<Int16x8, Add, Int16x8>), 2)                                      \
-  V(addSaturate, (BinaryFunc<Int16x8, AddSaturate, Int16x8>), 2)                      \
-  V(and, (BinaryFunc<Int16x8, And, Int16x8>), 2)                                      \
-  V(equal, (CompareFunc<Int16x8, Equal, Bool16x8>), 2)                                \
-  V(extractLane, (ExtractLane<Int16x8>), 2)                                           \
-  V(greaterThan, (CompareFunc<Int16x8, GreaterThan, Bool16x8>), 2)                    \
-  V(greaterThanOrEqual, (CompareFunc<Int16x8, GreaterThanOrEqual, Bool16x8>), 2)      \
-  V(lessThan, (CompareFunc<Int16x8, LessThan, Bool16x8>), 2)                          \
-  V(lessThanOrEqual, (CompareFunc<Int16x8, LessThanOrEqual, Bool16x8>), 2)            \
-  V(load, (Load<Int16x8, 8>), 2)                                                      \
-  V(mul, (BinaryFunc<Int16x8, Mul, Int16x8>), 2)                                      \
-  V(notEqual, (CompareFunc<Int16x8, NotEqual, Bool16x8>), 2)                          \
-  V(or, (BinaryFunc<Int16x8, Or, Int16x8>), 2)                                        \
-  V(sub, (BinaryFunc<Int16x8, Sub, Int16x8>), 2)                                      \
-  V(subSaturate, (BinaryFunc<Int16x8, SubSaturate, Int16x8>), 2)                      \
-  V(shiftLeftByScalar, (BinaryScalar<Int16x8, ShiftLeft>), 2)                         \
-  V(shiftRightByScalar, (BinaryScalar<Int16x8, ShiftRightArithmetic>), 2)             \
-  V(xor, (BinaryFunc<Int16x8, Xor, Int16x8>), 2)
-
-#define INT16X8_TERNARY_FUNCTION_LIST(V)                                              \
-  V(replaceLane, (ReplaceLane<Int16x8>), 3)                                           \
-  V(select, (Select<Int16x8, Bool16x8>), 3)                                           \
-  V(store, (Store<Int16x8, 8>), 3)
-
-#define INT16X8_SHUFFLE_FUNCTION_LIST(V)                                              \
-  V(swizzle, Swizzle<Int16x8>, 9)                                                     \
-  V(shuffle, Shuffle<Int16x8>, 10)
-
-#define INT16X8_FUNCTION_LIST(V)                                                      \
-  INT16X8_UNARY_FUNCTION_LIST(V)                                                      \
-  INT16X8_BINARY_FUNCTION_LIST(V)                                                     \
-  INT16X8_TERNARY_FUNCTION_LIST(V)                                                    \
-  INT16X8_SHUFFLE_FUNCTION_LIST(V)
-
-// Uint16x8.
-#define UINT16X8_UNARY_FUNCTION_LIST(V)                                               \
-  V(check, (UnaryFunc<Uint16x8, Identity, Uint16x8>), 1)                              \
-  V(fromFloat32x4Bits, (FuncConvertBits<Float32x4, Uint16x8>), 1)                     \
-  V(fromFloat64x2Bits, (FuncConvertBits<Float64x2, Uint16x8>), 1)                     \
-  V(fromInt8x16Bits,   (FuncConvertBits<Int8x16,   Uint16x8>), 1)                     \
-  V(fromInt16x8Bits,   (FuncConvertBits<Int16x8,   Uint16x8>), 1)                     \
-  V(fromInt32x4Bits,   (FuncConvertBits<Int32x4,   Uint16x8>), 1)                     \
-  V(fromUint8x16Bits,  (FuncConvertBits<Uint8x16,  Uint16x8>), 1)                     \
-  V(fromUint32x4Bits,  (FuncConvertBits<Uint32x4,  Uint16x8>), 1)                     \
-  V(neg, (UnaryFunc<Uint16x8, Neg, Uint16x8>), 1)                                     \
-  V(not, (UnaryFunc<Uint16x8, Not, Uint16x8>), 1)                                     \
-  V(splat, (FuncSplat<Uint16x8>), 1)
-
-#define UINT16X8_BINARY_FUNCTION_LIST(V)                                              \
-  V(add, (BinaryFunc<Uint16x8, Add, Uint16x8>), 2)                                    \
-  V(addSaturate, (BinaryFunc<Uint16x8, AddSaturate, Uint16x8>), 2)                    \
-  V(and, (BinaryFunc<Uint16x8, And, Uint16x8>), 2)                                    \
-  V(equal, (CompareFunc<Uint16x8, Equal, Bool16x8>), 2)                               \
-  V(extractLane, (ExtractLane<Uint16x8>), 2)                                          \
-  V(greaterThan, (CompareFunc<Uint16x8, GreaterThan, Bool16x8>), 2)                   \
-  V(greaterThanOrEqual, (CompareFunc<Uint16x8, GreaterThanOrEqual, Bool16x8>), 2)     \
-  V(lessThan, (CompareFunc<Uint16x8, LessThan, Bool16x8>), 2)                         \
-  V(lessThanOrEqual, (CompareFunc<Uint16x8, LessThanOrEqual, Bool16x8>), 2)           \
-  V(load, (Load<Uint16x8, 8>), 2)                                                     \
-  V(mul, (BinaryFunc<Uint16x8, Mul, Uint16x8>), 2)                                    \
-  V(notEqual, (CompareFunc<Uint16x8, NotEqual, Bool16x8>), 2)                         \
-  V(or, (BinaryFunc<Uint16x8, Or, Uint16x8>), 2)                                      \
-  V(sub, (BinaryFunc<Uint16x8, Sub, Uint16x8>), 2)                                    \
-  V(subSaturate, (BinaryFunc<Uint16x8, SubSaturate, Uint16x8>), 2)                    \
-  V(shiftLeftByScalar, (BinaryScalar<Uint16x8, ShiftLeft>), 2)                        \
-  V(shiftRightByScalar, (BinaryScalar<Uint16x8, ShiftRightLogical>), 2)               \
-  V(xor, (BinaryFunc<Uint16x8, Xor, Uint16x8>), 2)
-
-#define UINT16X8_TERNARY_FUNCTION_LIST(V)                                             \
-  V(replaceLane, (ReplaceLane<Uint16x8>), 3)                                          \
-  V(select, (Select<Uint16x8, Bool16x8>), 3)                                          \
-  V(store, (Store<Uint16x8, 8>), 3)
-
-#define UINT16X8_SHUFFLE_FUNCTION_LIST(V)                                             \
-  V(swizzle, Swizzle<Uint16x8>, 9)                                                    \
-  V(shuffle, Shuffle<Uint16x8>, 10)
-
-#define UINT16X8_FUNCTION_LIST(V)                                                     \
-  UINT16X8_UNARY_FUNCTION_LIST(V)                                                     \
-  UINT16X8_BINARY_FUNCTION_LIST(V)                                                    \
-  UINT16X8_TERNARY_FUNCTION_LIST(V)                                                   \
-  UINT16X8_SHUFFLE_FUNCTION_LIST(V)
-
-// Int32x4.
-#define INT32X4_UNARY_FUNCTION_LIST(V)                                                \
-  V(check, (UnaryFunc<Int32x4, Identity, Int32x4>), 1)                                \
-  V(fromFloat32x4,     (FuncConvert<Float32x4,     Int32x4>), 1)                      \
-  V(fromFloat32x4Bits, (FuncConvertBits<Float32x4, Int32x4>), 1)                      \
-  V(fromFloat64x2Bits, (FuncConvertBits<Float64x2, Int32x4>), 1)                      \
-  V(fromInt8x16Bits,   (FuncConvertBits<Int8x16,   Int32x4>), 1)                      \
-  V(fromInt16x8Bits,   (FuncConvertBits<Int16x8,   Int32x4>), 1)                      \
-  V(fromUint8x16Bits,  (FuncConvertBits<Uint8x16,  Int32x4>), 1)                      \
-  V(fromUint16x8Bits,  (FuncConvertBits<Uint16x8,  Int32x4>), 1)                      \
-  V(fromUint32x4Bits,  (FuncConvertBits<Uint32x4,  Int32x4>), 1)                      \
-  V(neg, (UnaryFunc<Int32x4, Neg, Int32x4>), 1)                                       \
-  V(not, (UnaryFunc<Int32x4, Not, Int32x4>), 1)                                       \
-  V(splat, (FuncSplat<Int32x4>), 0)
-
-#define INT32X4_BINARY_FUNCTION_LIST(V)                                               \
-  V(add, (BinaryFunc<Int32x4, Add, Int32x4>), 2)                                      \
-  V(and, (BinaryFunc<Int32x4, And, Int32x4>), 2)                                      \
-  V(equal, (CompareFunc<Int32x4, Equal, Bool32x4>), 2)                                \
-  V(extractLane, (ExtractLane<Int32x4>), 2)                                           \
-  V(greaterThan, (CompareFunc<Int32x4, GreaterThan, Bool32x4>), 2)                    \
-  V(greaterThanOrEqual, (CompareFunc<Int32x4, GreaterThanOrEqual, Bool32x4>), 2)      \
-  V(lessThan, (CompareFunc<Int32x4, LessThan, Bool32x4>), 2)                          \
-  V(lessThanOrEqual, (CompareFunc<Int32x4, LessThanOrEqual, Bool32x4>), 2)            \
-  V(load,  (Load<Int32x4, 4>), 2)                                                     \
-  V(load3, (Load<Int32x4, 3>), 2)                                                     \
-  V(load2, (Load<Int32x4, 2>), 2)                                                     \
-  V(load1, (Load<Int32x4, 1>), 2)                                                     \
-  V(mul, (BinaryFunc<Int32x4, Mul, Int32x4>), 2)                                      \
-  V(notEqual, (CompareFunc<Int32x4, NotEqual, Bool32x4>), 2)                          \
-  V(or, (BinaryFunc<Int32x4, Or, Int32x4>), 2)                                        \
-  V(sub, (BinaryFunc<Int32x4, Sub, Int32x4>), 2)                                      \
-  V(shiftLeftByScalar, (BinaryScalar<Int32x4, ShiftLeft>), 2)                         \
-  V(shiftRightByScalar, (BinaryScalar<Int32x4, ShiftRightArithmetic>), 2)             \
-  V(xor, (BinaryFunc<Int32x4, Xor, Int32x4>), 2)
-
-#define INT32X4_TERNARY_FUNCTION_LIST(V)                                              \
-  V(replaceLane, (ReplaceLane<Int32x4>), 3)                                           \
-  V(select, (Select<Int32x4, Bool32x4>), 3)                                           \
-  V(store,  (Store<Int32x4, 4>), 3)                                                   \
-  V(store3, (Store<Int32x4, 3>), 3)                                                   \
-  V(store2, (Store<Int32x4, 2>), 3)                                                   \
-  V(store1, (Store<Int32x4, 1>), 3)
-
-#define INT32X4_SHUFFLE_FUNCTION_LIST(V)                                              \
-  V(swizzle, Swizzle<Int32x4>, 5)                                                     \
-  V(shuffle, Shuffle<Int32x4>, 6)
-
-#define INT32X4_FUNCTION_LIST(V)                                                      \
-  INT32X4_UNARY_FUNCTION_LIST(V)                                                      \
-  INT32X4_BINARY_FUNCTION_LIST(V)                                                     \
-  INT32X4_TERNARY_FUNCTION_LIST(V)                                                    \
-  INT32X4_SHUFFLE_FUNCTION_LIST(V)
-
-// Uint32x4.
-#define UINT32X4_UNARY_FUNCTION_LIST(V)                                               \
-  V(check, (UnaryFunc<Uint32x4, Identity, Uint32x4>), 1)                              \
-  V(fromFloat32x4,     (FuncConvert<Float32x4,     Uint32x4>), 1)                     \
-  V(fromFloat32x4Bits, (FuncConvertBits<Float32x4, Uint32x4>), 1)                     \
-  V(fromFloat64x2Bits, (FuncConvertBits<Float64x2, Uint32x4>), 1)                     \
-  V(fromInt8x16Bits,   (FuncConvertBits<Int8x16,   Uint32x4>), 1)                     \
-  V(fromInt16x8Bits,   (FuncConvertBits<Int16x8,   Uint32x4>), 1)                     \
-  V(fromInt32x4Bits,   (FuncConvertBits<Int32x4,   Uint32x4>), 1)                     \
-  V(fromUint8x16Bits,  (FuncConvertBits<Uint8x16,  Uint32x4>), 1)                     \
-  V(fromUint16x8Bits,  (FuncConvertBits<Uint16x8,  Uint32x4>), 1)                     \
-  V(neg, (UnaryFunc<Uint32x4, Neg, Uint32x4>), 1)                                     \
-  V(not, (UnaryFunc<Uint32x4, Not, Uint32x4>), 1)                                     \
-  V(splat, (FuncSplat<Uint32x4>), 0)
-
-#define UINT32X4_BINARY_FUNCTION_LIST(V)                                              \
-  V(add, (BinaryFunc<Uint32x4, Add, Uint32x4>), 2)                                    \
-  V(and, (BinaryFunc<Uint32x4, And, Uint32x4>), 2)                                    \
-  V(equal, (CompareFunc<Uint32x4, Equal, Bool32x4>), 2)                               \
-  V(extractLane, (ExtractLane<Uint32x4>), 2)                                          \
-  V(greaterThan, (CompareFunc<Uint32x4, GreaterThan, Bool32x4>), 2)                   \
-  V(greaterThanOrEqual, (CompareFunc<Uint32x4, GreaterThanOrEqual, Bool32x4>), 2)     \
-  V(lessThan, (CompareFunc<Uint32x4, LessThan, Bool32x4>), 2)                         \
-  V(lessThanOrEqual, (CompareFunc<Uint32x4, LessThanOrEqual, Bool32x4>), 2)           \
-  V(load,  (Load<Uint32x4, 4>), 2)                                                    \
-  V(load3, (Load<Uint32x4, 3>), 2)                                                    \
-  V(load2, (Load<Uint32x4, 2>), 2)                                                    \
-  V(load1, (Load<Uint32x4, 1>), 2)                                                    \
-  V(mul, (BinaryFunc<Uint32x4, Mul, Uint32x4>), 2)                                    \
-  V(notEqual, (CompareFunc<Uint32x4, NotEqual, Bool32x4>), 2)                         \
-  V(or, (BinaryFunc<Uint32x4, Or, Uint32x4>), 2)                                      \
-  V(sub, (BinaryFunc<Uint32x4, Sub, Uint32x4>), 2)                                    \
-  V(shiftLeftByScalar, (BinaryScalar<Uint32x4, ShiftLeft>), 2)                        \
-  V(shiftRightByScalar, (BinaryScalar<Uint32x4, ShiftRightLogical>), 2)               \
-  V(xor, (BinaryFunc<Uint32x4, Xor, Uint32x4>), 2)
-
-#define UINT32X4_TERNARY_FUNCTION_LIST(V)                                             \
-  V(replaceLane, (ReplaceLane<Uint32x4>), 3)                                          \
-  V(select, (Select<Uint32x4, Bool32x4>), 3)                                          \
-  V(store,  (Store<Uint32x4, 4>), 3)                                                  \
-  V(store3, (Store<Uint32x4, 3>), 3)                                                  \
-  V(store2, (Store<Uint32x4, 2>), 3)                                                  \
-  V(store1, (Store<Uint32x4, 1>), 3)
-
-#define UINT32X4_SHUFFLE_FUNCTION_LIST(V)                                             \
-  V(swizzle, Swizzle<Uint32x4>, 5)                                                    \
-  V(shuffle, Shuffle<Uint32x4>, 6)
-
-#define UINT32X4_FUNCTION_LIST(V)                                                     \
-  UINT32X4_UNARY_FUNCTION_LIST(V)                                                     \
-  UINT32X4_BINARY_FUNCTION_LIST(V)                                                    \
-  UINT32X4_TERNARY_FUNCTION_LIST(V)                                                   \
-  UINT32X4_SHUFFLE_FUNCTION_LIST(V)
-
-/*
- * The FOREACH macros below partition all of the SIMD operations into disjoint
- * sets.
- */
-
-// Operations available on all SIMD types. Mixed arity.
-#define FOREACH_COMMON_SIMD_OP(_)     \
-    _(extractLane)                    \
-    _(replaceLane)                    \
-    _(check)                          \
-    _(splat)
-
-// Lanewise operations available on numeric SIMD types.
-// Include lane-wise select here since it is not arithmetic and defined on
-// numeric types too.
-#define FOREACH_LANE_SIMD_OP(_)       \
-    _(select)                         \
-    _(swizzle)                        \
-    _(shuffle)
-
-// Memory operations available on numeric SIMD types.
-#define FOREACH_MEMORY_SIMD_OP(_)     \
-    _(load)                           \
-    _(store)
-
-// Memory operations available on numeric X4 SIMD types.
-#define FOREACH_MEMORY_X4_SIMD_OP(_)  \
-    _(load1)                          \
-    _(load2)                          \
-    _(load3)                          \
-    _(store1)                         \
-    _(store2)                         \
-    _(store3)
-
-// Unary operations on Bool vectors.
-#define FOREACH_BOOL_SIMD_UNOP(_)     \
-    _(allTrue)                        \
-    _(anyTrue)
-
-// Unary bitwise SIMD operators defined on all integer and boolean SIMD types.
-#define FOREACH_BITWISE_SIMD_UNOP(_)  \
-    _(not)
-
-// Binary bitwise SIMD operators defined on all integer and boolean SIMD types.
-#define FOREACH_BITWISE_SIMD_BINOP(_) \
-    _(and)                            \
-    _(or)                             \
-    _(xor)
-
-// Bitwise shifts defined on integer SIMD types.
-#define FOREACH_SHIFT_SIMD_OP(_)      \
-    _(shiftLeftByScalar)              \
-    _(shiftRightByScalar)
-
-// Unary arithmetic operators defined on numeric SIMD types.
-#define FOREACH_NUMERIC_SIMD_UNOP(_)  \
-    _(neg)
-
-// Binary arithmetic operators defined on numeric SIMD types.
-#define FOREACH_NUMERIC_SIMD_BINOP(_) \
-    _(add)                            \
-    _(sub)                            \
-    _(mul)
-
-// Unary arithmetic operators defined on floating point SIMD types.
-#define FOREACH_FLOAT_SIMD_UNOP(_)    \
-    _(abs)                            \
-    _(sqrt)                           \
-    _(reciprocalApproximation)        \
-    _(reciprocalSqrtApproximation)
-
-// Binary arithmetic operators defined on floating point SIMD types.
-#define FOREACH_FLOAT_SIMD_BINOP(_)   \
-    _(div)                            \
-    _(max)                            \
-    _(min)                            \
-    _(maxNum)                         \
-    _(minNum)
-
-// Binary operations on small integer (< 32 bits) vectors.
-#define FOREACH_SMINT_SIMD_BINOP(_)   \
-    _(addSaturate)                    \
-    _(subSaturate)
-
-// Comparison operators defined on numeric SIMD types.
-#define FOREACH_COMP_SIMD_OP(_)       \
-    _(lessThan)                       \
-    _(lessThanOrEqual)                \
-    _(equal)                          \
-    _(notEqual)                       \
-    _(greaterThan)                    \
-    _(greaterThanOrEqual)
-
-/*
- * All SIMD operations, excluding casts.
- */
-#define FORALL_SIMD_NONCAST_OP(_)     \
-    FOREACH_COMMON_SIMD_OP(_)         \
-    FOREACH_LANE_SIMD_OP(_)           \
-    FOREACH_MEMORY_SIMD_OP(_)         \
-    FOREACH_MEMORY_X4_SIMD_OP(_)      \
-    FOREACH_BOOL_SIMD_UNOP(_)         \
-    FOREACH_BITWISE_SIMD_UNOP(_)      \
-    FOREACH_BITWISE_SIMD_BINOP(_)     \
-    FOREACH_SHIFT_SIMD_OP(_)          \
-    FOREACH_NUMERIC_SIMD_UNOP(_)      \
-    FOREACH_NUMERIC_SIMD_BINOP(_)     \
-    FOREACH_FLOAT_SIMD_UNOP(_)        \
-    FOREACH_FLOAT_SIMD_BINOP(_)       \
-    FOREACH_SMINT_SIMD_BINOP(_)       \
-    FOREACH_COMP_SIMD_OP(_)
-
-/*
- * All operations on integer SIMD types, excluding casts and
- * FOREACH_MEMORY_X4_OP.
- */
-#define FORALL_INT_SIMD_OP(_)         \
-    FOREACH_COMMON_SIMD_OP(_)         \
-    FOREACH_LANE_SIMD_OP(_)           \
-    FOREACH_MEMORY_SIMD_OP(_)         \
-    FOREACH_BITWISE_SIMD_UNOP(_)      \
-    FOREACH_BITWISE_SIMD_BINOP(_)     \
-    FOREACH_SHIFT_SIMD_OP(_)          \
-    FOREACH_NUMERIC_SIMD_UNOP(_)      \
-    FOREACH_NUMERIC_SIMD_BINOP(_)     \
-    FOREACH_COMP_SIMD_OP(_)
-
-/*
- * All operations on floating point SIMD types, excluding casts and
- * FOREACH_MEMORY_X4_OP.
- */
-#define FORALL_FLOAT_SIMD_OP(_)       \
-    FOREACH_COMMON_SIMD_OP(_)         \
-    FOREACH_LANE_SIMD_OP(_)           \
-    FOREACH_MEMORY_SIMD_OP(_)         \
-    FOREACH_NUMERIC_SIMD_UNOP(_)      \
-    FOREACH_NUMERIC_SIMD_BINOP(_)     \
-    FOREACH_FLOAT_SIMD_UNOP(_)        \
-    FOREACH_FLOAT_SIMD_BINOP(_)       \
-    FOREACH_COMP_SIMD_OP(_)
-
-/*
- * All operations on Bool SIMD types.
- *
- * These types don't have casts, so no need to specialize.
- */
-#define FORALL_BOOL_SIMD_OP(_)        \
-    FOREACH_COMMON_SIMD_OP(_)         \
-    FOREACH_BOOL_SIMD_UNOP(_)         \
-    FOREACH_BITWISE_SIMD_UNOP(_)      \
-    FOREACH_BITWISE_SIMD_BINOP(_)
-
-/*
- * The sets of cast operations are listed per type below.
- *
- * These sets are not disjoint.
- */
-
-#define FOREACH_INT8X16_SIMD_CAST(_)  \
-    _(fromFloat32x4Bits)              \
-    _(fromFloat64x2Bits)              \
-    _(fromInt16x8Bits)                \
-    _(fromInt32x4Bits)
-
-#define FOREACH_INT16X8_SIMD_CAST(_)  \
-    _(fromFloat32x4Bits)              \
-    _(fromFloat64x2Bits)              \
-    _(fromInt8x16Bits)                \
-    _(fromInt32x4Bits)
-
-#define FOREACH_INT32X4_SIMD_CAST(_)  \
-    _(fromFloat32x4)                  \
-    _(fromFloat32x4Bits)              \
-    _(fromFloat64x2Bits)              \
-    _(fromInt8x16Bits)                \
-    _(fromInt16x8Bits)
-
-#define FOREACH_FLOAT32X4_SIMD_CAST(_)\
-    _(fromFloat64x2Bits)              \
-    _(fromInt8x16Bits)                \
-    _(fromInt16x8Bits)                \
-    _(fromInt32x4)                    \
-    _(fromInt32x4Bits)
-
-#define FOREACH_FLOAT64X2_SIMD_CAST(_)\
-    _(fromFloat32x4Bits)              \
-    _(fromInt8x16Bits)                \
-    _(fromInt16x8Bits)                \
-    _(fromInt32x4Bits)
-
-// All operations on Int32x4.
-#define FORALL_INT32X4_SIMD_OP(_)     \
-    FORALL_INT_SIMD_OP(_)             \
-    FOREACH_MEMORY_X4_SIMD_OP(_)      \
-    FOREACH_INT32X4_SIMD_CAST(_)
-
-// All operations on Float32X4
-#define FORALL_FLOAT32X4_SIMD_OP(_)   \
-    FORALL_FLOAT_SIMD_OP(_)           \
-    FOREACH_MEMORY_X4_SIMD_OP(_)      \
-    FOREACH_FLOAT32X4_SIMD_CAST(_)
-
-/*
- * All SIMD operations assuming only 32x4 types exist.
- * This is used in the current asm.js impl.
- */
-#define FORALL_SIMD_ASMJS_OP(_)       \
-    FORALL_SIMD_NONCAST_OP(_)         \
-    _(fromFloat32x4)                  \
-    _(fromFloat32x4Bits)              \
-    _(fromInt8x16Bits)                \
-    _(fromInt16x8Bits)                \
-    _(fromInt32x4)                    \
-    _(fromInt32x4Bits)                \
-    _(fromUint8x16Bits)               \
-    _(fromUint16x8Bits)               \
-    _(fromUint32x4)                   \
-    _(fromUint32x4Bits)
-
-// All operations on Int8x16 or Uint8x16 in the asm.js world.
-// Note: this does not include conversions and casts to/from Uint8x16 because
-// this list is shared between Int8x16 and Uint8x16.
-#define FORALL_INT8X16_ASMJS_OP(_)    \
-    FORALL_INT_SIMD_OP(_)             \
-    FOREACH_SMINT_SIMD_BINOP(_)       \
-    _(fromInt16x8Bits)                \
-    _(fromInt32x4Bits)                \
-    _(fromFloat32x4Bits)
-
-// All operations on Int16x8 or Uint16x8 in the asm.js world.
-// Note: this does not include conversions and casts to/from Uint16x8 because
-// this list is shared between Int16x8 and Uint16x8.
-#define FORALL_INT16X8_ASMJS_OP(_)    \
-    FORALL_INT_SIMD_OP(_)             \
-    FOREACH_SMINT_SIMD_BINOP(_)       \
-    _(fromInt8x16Bits)                \
-    _(fromInt32x4Bits)                \
-    _(fromFloat32x4Bits)
-
-// All operations on Int32x4 or Uint32x4 in the asm.js world.
-// Note: this does not include conversions and casts to/from Uint32x4 because
-// this list is shared between Int32x4 and Uint32x4.
-#define FORALL_INT32X4_ASMJS_OP(_)    \
-    FORALL_INT_SIMD_OP(_)             \
-    FOREACH_MEMORY_X4_SIMD_OP(_)      \
-    _(fromInt8x16Bits)                \
-    _(fromInt16x8Bits)                \
-    _(fromFloat32x4)                  \
-    _(fromFloat32x4Bits)
-
-// All operations on Float32X4 in the asm.js world.
-#define FORALL_FLOAT32X4_ASMJS_OP(_)  \
-    FORALL_FLOAT_SIMD_OP(_)           \
-    FOREACH_MEMORY_X4_SIMD_OP(_)      \
-    _(fromInt8x16Bits)                \
-    _(fromInt16x8Bits)                \
-    _(fromInt32x4Bits)                \
-    _(fromInt32x4)                    \
-    _(fromUint32x4)
-
-namespace js {
-
-// Complete set of SIMD types.
-// It must be kept in sync with the enumeration of values in
-// TypedObjectConstants.h; in particular we need to ensure that Count is
-// appropriately set with respect to the number of actual types.
-enum class SimdType {
-    Int8x16   = JS_SIMDTYPEREPR_INT8X16,
-    Int16x8   = JS_SIMDTYPEREPR_INT16X8,
-    Int32x4   = JS_SIMDTYPEREPR_INT32X4,
-    Uint8x16  = JS_SIMDTYPEREPR_UINT8X16,
-    Uint16x8  = JS_SIMDTYPEREPR_UINT16X8,
-    Uint32x4  = JS_SIMDTYPEREPR_UINT32X4,
-    Float32x4 = JS_SIMDTYPEREPR_FLOAT32X4,
-    Float64x2 = JS_SIMDTYPEREPR_FLOAT64X2,
-    Bool8x16  = JS_SIMDTYPEREPR_BOOL8X16,
-    Bool16x8  = JS_SIMDTYPEREPR_BOOL16X8,
-    Bool32x4  = JS_SIMDTYPEREPR_BOOL32X4,
-    Bool64x2  = JS_SIMDTYPEREPR_BOOL64X2,
-    Count
-};
-
-// The integer SIMD types have a lot of operations that do the exact same thing
-// for signed and unsigned integer types. Sometimes it is simpler to treat
-// signed and unsigned integer SIMD types as the same type, using a SimdSign to
-// distinguish the few cases where there is a difference.
-enum class SimdSign {
-    // Signedness is not applicable to this type. (i.e., Float or Bool).
-    NotApplicable,
-    // Treat as an unsigned integer with a range 0 .. 2^N-1.
-    Unsigned,
-    // Treat as a signed integer in two's complement encoding.
-    Signed,
-};
-
-// Get the signedness of a SIMD type.
-inline SimdSign
-GetSimdSign(SimdType t)
-{
-    switch(t) {
-      case SimdType::Int8x16:
-      case SimdType::Int16x8:
-      case SimdType::Int32x4:
-        return SimdSign::Signed;
-
-      case SimdType::Uint8x16:
-      case SimdType::Uint16x8:
-      case SimdType::Uint32x4:
-        return SimdSign::Unsigned;
-
-      default:
-        return SimdSign::NotApplicable;
-    }
-}
-
-inline bool
-IsSignedIntSimdType(SimdType type)
-{
-    return GetSimdSign(type) == SimdSign::Signed;
-}
-
-// Get the boolean SIMD type with the same shape as t.
-//
-// This is the result type of a comparison operation, and it can also be used to
-// identify the geometry of a SIMD type.
-inline SimdType
-GetBooleanSimdType(SimdType t)
-{
-    switch(t) {
-      case SimdType::Int8x16:
-      case SimdType::Uint8x16:
-      case SimdType::Bool8x16:
-        return SimdType::Bool8x16;
-
-      case SimdType::Int16x8:
-      case SimdType::Uint16x8:
-      case SimdType::Bool16x8:
-        return SimdType::Bool16x8;
-
-      case SimdType::Int32x4:
-      case SimdType::Uint32x4:
-      case SimdType::Float32x4:
-      case SimdType::Bool32x4:
-        return SimdType::Bool32x4;
-
-      case SimdType::Float64x2:
-      case SimdType::Bool64x2:
-        return SimdType::Bool64x2;
-
-      case SimdType::Count:
-        break;
-    }
-    MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("Bad SIMD type");
-}
-
-// Get the number of lanes in a SIMD type.
-inline unsigned
-GetSimdLanes(SimdType t)
-{
-    switch(t) {
-      case SimdType::Int8x16:
-      case SimdType::Uint8x16:
-      case SimdType::Bool8x16:
-        return 16;
-
-      case SimdType::Int16x8:
-      case SimdType::Uint16x8:
-      case SimdType::Bool16x8:
-        return 8;
-
-      case SimdType::Int32x4:
-      case SimdType::Uint32x4:
-      case SimdType::Float32x4:
-      case SimdType::Bool32x4:
-        return 4;
-
-      case SimdType::Float64x2:
-      case SimdType::Bool64x2:
-        return 2;
-
-      case SimdType::Count:
-        break;
-    }
-    MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("Bad SIMD type");
-}
-
-// Complete set of SIMD operations.
-//
-// No SIMD types implement all of these operations.
-//
-// C++ defines keywords and/or/xor/not, so prepend Fn_ to all named functions to
-// avoid clashes.
-//
-// Note: because of a gcc < v4.8's compiler bug, uint8_t can't be used as the
-// storage class here. See bug 1243810. See also
-// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64037 .
-enum class SimdOperation {
-    // The constructor call. No Fn_ prefix here.
-    Constructor,
-
-    // All the operations, except for casts.
-#define DEFOP(x) Fn_##x,
-    FORALL_SIMD_NONCAST_OP(DEFOP)
-#undef DEFOP
-
-    // Int <-> Float conversions.
-    Fn_fromInt32x4,
-    Fn_fromUint32x4,
-    Fn_fromFloat32x4,
-
-    // Bitcasts. One for each type with a memory representation.
-    Fn_fromInt8x16Bits,
-    Fn_fromInt16x8Bits,
-    Fn_fromInt32x4Bits,
-    Fn_fromUint8x16Bits,
-    Fn_fromUint16x8Bits,
-    Fn_fromUint32x4Bits,
-    Fn_fromFloat32x4Bits,
-    Fn_fromFloat64x2Bits,
-
-    Last = Fn_fromFloat64x2Bits
-};
-
-} // namespace js
-
-#endif /* builtin_SIMDConstants_h */
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -3975,22 +3975,17 @@ ShellCloneAndExecuteScript(JSContext* cx
     args.rval().setUndefined();
     return true;
 }
 
 static bool
 IsSimdAvailable(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
-#if defined(JS_CODEGEN_NONE) || !defined(ENABLE_SIMD)
-    bool available = false;
-#else
-    bool available = cx->jitSupportsSimd();
-#endif
-    args.rval().set(BooleanValue(available));
+    args.rval().set(BooleanValue(cx->jitSupportsSimd()));
     return true;
 }
 
 static bool
 ByteSize(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     mozilla::MallocSizeOf mallocSizeOf = cx->runtime()->debuggerMallocSizeOf;
--- a/js/src/builtin/TypedObject.cpp
+++ b/js/src/builtin/TypedObject.cpp
@@ -6,17 +6,16 @@
 
 #include "builtin/TypedObject-inl.h"
 
 #include "mozilla/Casting.h"
 #include "mozilla/CheckedInt.h"
 
 #include "jsutil.h"
 
-#include "builtin/SIMDConstants.h"
 #include "gc/Marking.h"
 #include "js/Vector.h"
 #include "util/StringBuffer.h"
 #include "vm/GlobalObject.h"
 #include "vm/JSFunction.h"
 #include "vm/Realm.h"
 #include "vm/SelfHosting.h"
 #include "vm/StringType.h"
@@ -239,20 +238,16 @@ ScalarTypeDescr::alignment(Type t)
 ScalarTypeDescr::typeName(Type type)
 {
     switch (type) {
 #define NUMERIC_TYPE_TO_STRING(constant_, type_, name_) \
         case constant_: return #name_;
         JS_FOR_EACH_SCALAR_TYPE_REPR(NUMERIC_TYPE_TO_STRING)
 #undef NUMERIC_TYPE_TO_STRING
       case Scalar::Int64:
-      case Scalar::Float32x4:
-      case Scalar::Int8x16:
-      case Scalar::Int16x8:
-      case Scalar::Int32x4:
       case Scalar::MaxTypedArrayViewType:
         break;
     }
     MOZ_CRASH("Invalid type");
 }
 
 bool
 ScalarTypeDescr::call(JSContext* cx, unsigned argc, Value* vp)
@@ -280,20 +275,16 @@ ScalarTypeDescr::call(JSContext* cx, uns
           type_ converted = ConvertScalar<type_>(number);                     \
           args.rval().setNumber((double) converted);                          \
           return true;                                                        \
       }
 
         JS_FOR_EACH_SCALAR_TYPE_REPR(SCALARTYPE_CALL)
 #undef SCALARTYPE_CALL
       case Scalar::Int64:
-      case Scalar::Float32x4:
-      case Scalar::Int8x16:
-      case Scalar::Int16x8:
-      case Scalar::Int32x4:
       case Scalar::MaxTypedArrayViewType:
         MOZ_CRASH();
     }
     return true;
 }
 
 /***************************************************************************
  * Reference type objects
@@ -397,60 +388,16 @@ js::ReferenceTypeDescr::call(JSContext* 
         return true;
       }
     }
 
     MOZ_CRASH("Unhandled Reference type");
 }
 
 /***************************************************************************
- * SIMD type objects
- *
- * Note: these are partially defined in SIMD.cpp
- */
-
-SimdType
-SimdTypeDescr::type() const {
-    uint32_t t = uint32_t(getReservedSlot(JS_DESCR_SLOT_TYPE).toInt32());
-    MOZ_ASSERT(t < uint32_t(SimdType::Count));
-    return SimdType(t);
-}
-
-uint32_t
-SimdTypeDescr::size(SimdType t)
-{
-    MOZ_ASSERT(unsigned(t) < unsigned(SimdType::Count));
-    switch (t) {
-      case SimdType::Int8x16:
-      case SimdType::Int16x8:
-      case SimdType::Int32x4:
-      case SimdType::Uint8x16:
-      case SimdType::Uint16x8:
-      case SimdType::Uint32x4:
-      case SimdType::Float32x4:
-      case SimdType::Float64x2:
-      case SimdType::Bool8x16:
-      case SimdType::Bool16x8:
-      case SimdType::Bool32x4:
-      case SimdType::Bool64x2:
-        return 16;
-      case SimdType::Count:
-        break;
-    }
-    MOZ_CRASH("unexpected SIMD type");
-}
-
-uint32_t
-SimdTypeDescr::alignment(SimdType t)
-{
-    MOZ_ASSERT(unsigned(t) < unsigned(SimdType::Count));
-    return size(t);
-}
-
-/***************************************************************************
  * ArrayMetaTypeDescr class
  */
 
 /*
  * For code like:
  *
  *   var A = new TypedObject.ArrayType(uint8, 10);
  *   var S = new TypedObject.StructType({...});
@@ -1661,17 +1608,16 @@ OutlineTypedObject::obj_trace(JSTracer* 
 }
 
 bool
 TypeDescr::hasProperty(const JSAtomState& names, jsid id)
 {
     switch (kind()) {
       case type::Scalar:
       case type::Reference:
-      case type::Simd:
         return false;
 
       case type::Array:
       {
         uint32_t index;
         return IdIsIndex(id, &index) || JSID_IS_ATOM(id, names.length);
       }
 
@@ -1734,17 +1680,16 @@ TypedObject::obj_defineProperty(JSContex
 
 bool
 TypedObject::obj_hasProperty(JSContext* cx, HandleObject obj, HandleId id, bool* foundp)
 {
     Rooted<TypedObject*> typedObj(cx, &obj->as<TypedObject>());
     switch (typedObj->typeDescr().kind()) {
       case type::Scalar:
       case type::Reference:
-      case type::Simd:
         break;
 
       case type::Array: {
         if (JSID_IS_ATOM(id, cx->names().length)) {
             *foundp = true;
             return true;
         }
         uint32_t index;
@@ -1786,19 +1731,16 @@ TypedObject::obj_getProperty(JSContext* 
 
     // Handle everything else here:
 
     switch (typedObj->typeDescr().kind()) {
       case type::Scalar:
       case type::Reference:
         break;
 
-      case type::Simd:
-        break;
-
       case type::Array:
         if (JSID_IS_ATOM(id, cx->names().length)) {
             if (!typedObj->isAttached()) {
                 JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
                                           JSMSG_TYPEDOBJECT_HANDLE_UNATTACHED);
                 return false;
             }
 
@@ -1835,17 +1777,16 @@ TypedObject::obj_getElement(JSContext* c
 {
     MOZ_ASSERT(obj->is<TypedObject>());
     Rooted<TypedObject*> typedObj(cx, &obj->as<TypedObject>());
     Rooted<TypeDescr*> descr(cx, &typedObj->typeDescr());
 
     switch (descr->kind()) {
       case type::Scalar:
       case type::Reference:
-      case type::Simd:
       case type::Struct:
         break;
 
       case type::Array:
         return obj_getArrayElement(cx, typedObj, descr, index, vp);
     }
 
     RootedObject proto(cx, obj->staticPrototype());
@@ -1881,19 +1822,16 @@ TypedObject::obj_setProperty(JSContext* 
 {
     Rooted<TypedObject*> typedObj(cx, &obj->as<TypedObject>());
 
     switch (typedObj->typeDescr().kind()) {
       case type::Scalar:
       case type::Reference:
         break;
 
-      case type::Simd:
-        break;
-
       case type::Array: {
         if (JSID_IS_ATOM(id, cx->names().length)) {
             if (receiver.isObject() && obj == &receiver.toObject()) {
                 JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
                                           JSMSG_CANT_REDEFINE_ARRAY_LENGTH);
                 return false;
             }
             return result.failReadOnly();
@@ -1951,17 +1889,16 @@ TypedObject::obj_getOwnPropertyDescripto
         JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_TYPEDOBJECT_HANDLE_UNATTACHED);
         return false;
     }
 
     Rooted<TypeDescr*> descr(cx, &typedObj->typeDescr());
     switch (descr->kind()) {
       case type::Scalar:
       case type::Reference:
-      case type::Simd:
         break;
 
       case type::Array:
       {
         uint32_t index;
         if (IdIsIndex(id, &index)) {
             if (!obj_getArrayElement(cx, typedObj, descr, index, desc.value()))
                 return false;
@@ -2005,17 +1942,16 @@ TypedObject::obj_getOwnPropertyDescripto
 static bool
 IsOwnId(JSContext* cx, HandleObject obj, HandleId id)
 {
     uint32_t index;
     Rooted<TypedObject*> typedObj(cx, &obj->as<TypedObject>());
     switch (typedObj->typeDescr().kind()) {
       case type::Scalar:
       case type::Reference:
-      case type::Simd:
         return false;
 
       case type::Array:
         return IdIsIndex(id, &index) || JSID_IS_ATOM(id, cx->names().length);
 
       case type::Struct:
         size_t index;
         if (typedObj->typeDescr().as<StructTypeDescr>().fieldIndex(id, &index))
@@ -2044,18 +1980,17 @@ TypedObject::obj_newEnumerate(JSContext*
 {
     MOZ_ASSERT(obj->is<TypedObject>());
     Rooted<TypedObject*> typedObj(cx, &obj->as<TypedObject>());
     Rooted<TypeDescr*> descr(cx, &typedObj->typeDescr());
 
     RootedId id(cx);
     switch (descr->kind()) {
       case type::Scalar:
-      case type::Reference:
-      case type::Simd: {
+      case type::Reference: {
         // Nothing to enumerate.
         break;
       }
 
       case type::Array: {
         if (!properties.reserve(typedObj->length()))
             return false;
 
@@ -2530,32 +2465,16 @@ js::GetTypedObjectModule(JSContext* cx, 
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     Rooted<GlobalObject*> global(cx, cx->global());
     MOZ_ASSERT(global);
     args.rval().setObject(global->getTypedObjectModule());
     return true;
 }
 
-bool
-js::GetSimdTypeDescr(JSContext* cx, unsigned argc, Value* vp)
-{
-    CallArgs args = CallArgsFromVp(argc, vp);
-    MOZ_ASSERT(args.length() == 1);
-    MOZ_ASSERT(args[0].isInt32());
-    // One of the JS_SIMDTYPEREPR_* constants / a SimdType enum value.
-    // getOrCreateSimdTypeDescr() will do the range check.
-    int32_t simdTypeRepr = args[0].toInt32();
-    Rooted<GlobalObject*> global(cx, cx->global());
-    MOZ_ASSERT(global);
-    auto* obj = GlobalObject::getOrCreateSimdTypeDescr(cx, global, SimdType(simdTypeRepr));
-    args.rval().setObject(*obj);
-    return true;
-}
-
 #define JS_STORE_SCALAR_CLASS_IMPL(_constant, T, _name)                         \
 bool                                                                            \
 js::StoreScalar##T::Func(JSContext* cx, unsigned argc, Value* vp)               \
 {                                                                               \
     CallArgs args = CallArgsFromVp(argc, vp);                                   \
     MOZ_ASSERT(args.length() == 3);                                             \
     MOZ_ASSERT(args[0].isObject() && args[0].toObject().is<TypedObject>());     \
     MOZ_ASSERT(args[1].isInt32());                                              \
@@ -2736,17 +2655,16 @@ visitReferences(TypeDescr& descr,
                 uint8_t* mem,
                 V& visitor)
 {
     if (descr.transparent())
         return;
 
     switch (descr.kind()) {
       case type::Scalar:
-      case type::Simd:
         return;
 
       case type::Reference:
         visitor.visitReference(descr.as<ReferenceTypeDescr>(), mem);
         return;
 
       case type::Array:
       {
--- a/js/src/builtin/TypedObject.h
+++ b/js/src/builtin/TypedObject.h
@@ -116,29 +116,27 @@ static T ConvertScalar(double d)
     return T(n);
 }
 
 namespace type {
 
 enum Kind {
     Scalar = JS_TYPEREPR_SCALAR_KIND,
     Reference = JS_TYPEREPR_REFERENCE_KIND,
-    Simd = JS_TYPEREPR_SIMD_KIND,
     Struct = JS_TYPEREPR_STRUCT_KIND,
     Array = JS_TYPEREPR_ARRAY_KIND
 };
 
 } // namespace type
 
 ///////////////////////////////////////////////////////////////////////////
 // Typed Prototypes
 
 class SimpleTypeDescr;
 class ComplexTypeDescr;
-class SimdTypeDescr;
 class StructTypeDescr;
 class TypedProto;
 
 /*
  * The prototype for a typed object.
  */
 class TypedProto : public NativeObject
 {
@@ -250,24 +248,16 @@ class ScalarTypeDescr : public SimpleTyp
         static_assert(Scalar::Uint32 == JS_SCALARTYPEREPR_UINT32,
                       "TypedObjectConstants.h must be consistent with Scalar::Type");
         static_assert(Scalar::Float32 == JS_SCALARTYPEREPR_FLOAT32,
                       "TypedObjectConstants.h must be consistent with Scalar::Type");
         static_assert(Scalar::Float64 == JS_SCALARTYPEREPR_FLOAT64,
                       "TypedObjectConstants.h must be consistent with Scalar::Type");
         static_assert(Scalar::Uint8Clamped == JS_SCALARTYPEREPR_UINT8_CLAMPED,
                       "TypedObjectConstants.h must be consistent with Scalar::Type");
-        static_assert(Scalar::Float32x4 == JS_SCALARTYPEREPR_FLOAT32X4,
-                      "TypedObjectConstants.h must be consistent with Scalar::Type");
-        static_assert(Scalar::Int8x16 == JS_SCALARTYPEREPR_INT8X16,
-                      "TypedObjectConstants.h must be consistent with Scalar::Type");
-        static_assert(Scalar::Int16x8 == JS_SCALARTYPEREPR_INT16X8,
-                      "TypedObjectConstants.h must be consistent with Scalar::Type");
-        static_assert(Scalar::Int32x4 == JS_SCALARTYPEREPR_INT32X4,
-                      "TypedObjectConstants.h must be consistent with Scalar::Type");
 
         return Type(getReservedSlot(JS_DESCR_SLOT_TYPE).toInt32());
     }
 
     static MOZ_MUST_USE bool call(JSContext* cx, unsigned argc, Value* vp);
 };
 
 // Enumerates the cases of ScalarTypeDescr::Type which have
@@ -335,35 +325,16 @@ class ComplexTypeDescr : public TypeDesc
   public:
     // Returns the prototype that instances of this type descriptor
     // will have.
     TypedProto& instancePrototype() const {
         return getReservedSlot(JS_DESCR_SLOT_TYPROTO).toObject().as<TypedProto>();
     }
 };
 
-enum class SimdType;
-
-/*
- * SIMD Type descriptors.
- */
-class SimdTypeDescr : public ComplexTypeDescr
-{
-  public:
-    static const type::Kind Kind = type::Simd;
-    static const bool Opaque = false;
-    static const Class class_;
-    static uint32_t size(SimdType t);
-    static uint32_t alignment(SimdType t);
-    static MOZ_MUST_USE bool call(JSContext* cx, unsigned argc, Value* vp);
-    static bool is(const Value& v);
-
-    SimdType type() const;
-};
-
 bool IsTypedObjectClass(const Class* clasp); // Defined below
 bool IsTypedObjectArray(JSObject& obj);
 
 MOZ_MUST_USE bool CreateUserSizeAndAlignmentProperties(JSContext* cx, HandleTypeDescr obj);
 
 class ArrayTypeDescr;
 
 /*
@@ -789,26 +760,16 @@ class InlineTransparentTypedObject : pub
 
 // Class for an opaque typed object with inline data and no array buffer.
 class InlineOpaqueTypedObject : public InlineTypedObject
 {
   public:
     static const Class class_;
 };
 
-// Class for the global SIMD object.
-class SimdObject : public NativeObject
-{
-  public:
-    static const Class class_;
-    static MOZ_MUST_USE bool toString(JSContext* cx, unsigned int argc, Value* vp);
-    static MOZ_MUST_USE bool resolve(JSContext* cx, JS::HandleObject obj, JS::HandleId,
-                                     bool* resolved);
-};
-
 /*
  * Usage: NewOpaqueTypedObject(typeObj)
  *
  * Constructs a new, unattached instance of `Handle`.
  */
 MOZ_MUST_USE bool NewOpaqueTypedObject(JSContext* cx, unsigned argc, Value* vp);
 
 /*
@@ -897,26 +858,16 @@ MOZ_MUST_USE bool ClampToUint8(JSContext
  * to the various builtin type descriptors. These are currently
  * exported as immutable properties so it is safe for self-hosted code
  * to access them; eventually this should be linked into the module
  * system.
  */
 MOZ_MUST_USE bool GetTypedObjectModule(JSContext* cx, unsigned argc, Value* vp);
 
 /*
- * Usage: GetSimdTypeDescr(simdTypeRepr)
- *
- * Returns one of the SIMD type objects, identified by `simdTypeRepr` which must
- * be one of the JS_SIMDTYPEREPR_* constants.
- *
- * The SIMD pseudo-module must have been initialized for this to be safe.
- */
-MOZ_MUST_USE bool GetSimdTypeDescr(JSContext* cx, unsigned argc, Value* vp);
-
-/*
  * Usage: Store_int8(targetDatum, targetOffset, value)
  *        ...
  *        Store_uint8(targetDatum, targetOffset, value)
  *        ...
  *        Store_float32(targetDatum, targetOffset, value)
  *        Store_float64(targetDatum, targetOffset, value)
  *
  * Intrinsic function. Stores `value` into the memory referenced by
@@ -1040,18 +991,17 @@ IsSimpleTypeDescrClass(const Class* clas
     return clasp == &ScalarTypeDescr::class_ ||
            clasp == &ReferenceTypeDescr::class_;
 }
 
 inline bool
 IsComplexTypeDescrClass(const Class* clasp)
 {
     return clasp == &StructTypeDescr::class_ ||
-           clasp == &ArrayTypeDescr::class_ ||
-           clasp == &SimdTypeDescr::class_;
+           clasp == &ArrayTypeDescr::class_;
 }
 
 inline bool
 IsTypeDescrClass(const Class* clasp)
 {
     return IsSimpleTypeDescrClass(clasp) ||
            IsComplexTypeDescrClass(clasp);
 }
--- a/js/src/builtin/TypedObject.js
+++ b/js/src/builtin/TypedObject.js
@@ -48,19 +48,16 @@ function TypedObjectGet(descr, typedObj,
 
   switch (DESCR_KIND(descr)) {
   case JS_TYPEREPR_SCALAR_KIND:
     return TypedObjectGetScalar(descr, typedObj, offset);
 
   case JS_TYPEREPR_REFERENCE_KIND:
     return TypedObjectGetReference(descr, typedObj, offset);
 
-  case JS_TYPEREPR_SIMD_KIND:
-    return TypedObjectGetSimd(descr, typedObj, offset);
-
   case JS_TYPEREPR_ARRAY_KIND:
   case JS_TYPEREPR_STRUCT_KIND:
     return TypedObjectGetDerived(descr, typedObj, offset);
   }
 
   assert(false, "Unhandled kind: " + DESCR_KIND(descr));
   return undefined;
 }
@@ -132,154 +129,16 @@ function TypedObjectGetReference(descr, 
   case JS_REFERENCETYPEREPR_STRING:
     return Load_string(typedObj, offset);
   }
 
   assert(false, "Unhandled scalar type: " + type);
   return undefined;
 }
 
-function TypedObjectGetSimd(descr, typedObj, offset) {
-  var type = DESCR_TYPE(descr);
-  var simdTypeDescr = GetSimdTypeDescr(type);
-  switch (type) {
-  case JS_SIMDTYPEREPR_FLOAT32X4:
-    var x = Load_float32(typedObj, offset + 0);
-    var y = Load_float32(typedObj, offset + 4);
-    var z = Load_float32(typedObj, offset + 8);
-    var w = Load_float32(typedObj, offset + 12);
-    return simdTypeDescr(x, y, z, w);
-
-  case JS_SIMDTYPEREPR_FLOAT64X2:
-    var x = Load_float64(typedObj, offset + 0);
-    var y = Load_float64(typedObj, offset + 8);
-    return simdTypeDescr(x, y);
-
-  case JS_SIMDTYPEREPR_INT8X16:
-    var s0 = Load_int8(typedObj, offset + 0);
-    var s1 = Load_int8(typedObj, offset + 1);
-    var s2 = Load_int8(typedObj, offset + 2);
-    var s3 = Load_int8(typedObj, offset + 3);
-    var s4 = Load_int8(typedObj, offset + 4);
-    var s5 = Load_int8(typedObj, offset + 5);
-    var s6 = Load_int8(typedObj, offset + 6);
-    var s7 = Load_int8(typedObj, offset + 7);
-    var s8 = Load_int8(typedObj, offset + 8);
-    var s9 = Load_int8(typedObj, offset + 9);
-    var s10 = Load_int8(typedObj, offset + 10);
-    var s11 = Load_int8(typedObj, offset + 11);
-    var s12 = Load_int8(typedObj, offset + 12);
-    var s13 = Load_int8(typedObj, offset + 13);
-    var s14 = Load_int8(typedObj, offset + 14);
-    var s15 = Load_int8(typedObj, offset + 15);
-    return simdTypeDescr(s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15);
-
-  case JS_SIMDTYPEREPR_INT16X8:
-    var s0 = Load_int16(typedObj, offset + 0);
-    var s1 = Load_int16(typedObj, offset + 2);
-    var s2 = Load_int16(typedObj, offset + 4);
-    var s3 = Load_int16(typedObj, offset + 6);
-    var s4 = Load_int16(typedObj, offset + 8);
-    var s5 = Load_int16(typedObj, offset + 10);
-    var s6 = Load_int16(typedObj, offset + 12);
-    var s7 = Load_int16(typedObj, offset + 14);
-    return simdTypeDescr(s0, s1, s2, s3, s4, s5, s6, s7);
-
-  case JS_SIMDTYPEREPR_INT32X4:
-    var x = Load_int32(typedObj, offset + 0);
-    var y = Load_int32(typedObj, offset + 4);
-    var z = Load_int32(typedObj, offset + 8);
-    var w = Load_int32(typedObj, offset + 12);
-    return simdTypeDescr(x, y, z, w);
-
-  case JS_SIMDTYPEREPR_UINT8X16:
-    var s0 = Load_uint8(typedObj, offset + 0);
-    var s1 = Load_uint8(typedObj, offset + 1);
-    var s2 = Load_uint8(typedObj, offset + 2);
-    var s3 = Load_uint8(typedObj, offset + 3);
-    var s4 = Load_uint8(typedObj, offset + 4);
-    var s5 = Load_uint8(typedObj, offset + 5);
-    var s6 = Load_uint8(typedObj, offset + 6);
-    var s7 = Load_uint8(typedObj, offset + 7);
-    var s8 = Load_uint8(typedObj, offset + 8);
-    var s9 = Load_uint8(typedObj, offset + 9);
-    var s10 = Load_uint8(typedObj, offset + 10);
-    var s11 = Load_uint8(typedObj, offset + 11);
-    var s12 = Load_uint8(typedObj, offset + 12);
-    var s13 = Load_uint8(typedObj, offset + 13);
-    var s14 = Load_uint8(typedObj, offset + 14);
-    var s15 = Load_uint8(typedObj, offset + 15);
-    return simdTypeDescr(s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15);
-
-  case JS_SIMDTYPEREPR_UINT16X8:
-    var s0 = Load_uint16(typedObj, offset + 0);
-    var s1 = Load_uint16(typedObj, offset + 2);
-    var s2 = Load_uint16(typedObj, offset + 4);
-    var s3 = Load_uint16(typedObj, offset + 6);
-    var s4 = Load_uint16(typedObj, offset + 8);
-    var s5 = Load_uint16(typedObj, offset + 10);
-    var s6 = Load_uint16(typedObj, offset + 12);
-    var s7 = Load_uint16(typedObj, offset + 14);
-    return simdTypeDescr(s0, s1, s2, s3, s4, s5, s6, s7);
-
-  case JS_SIMDTYPEREPR_UINT32X4:
-    var x = Load_uint32(typedObj, offset + 0);
-    var y = Load_uint32(typedObj, offset + 4);
-    var z = Load_uint32(typedObj, offset + 8);
-    var w = Load_uint32(typedObj, offset + 12);
-    return simdTypeDescr(x, y, z, w);
-
-  case JS_SIMDTYPEREPR_BOOL8X16:
-    var s0 = Load_int8(typedObj, offset + 0);
-    var s1 = Load_int8(typedObj, offset + 1);
-    var s2 = Load_int8(typedObj, offset + 2);
-    var s3 = Load_int8(typedObj, offset + 3);
-    var s4 = Load_int8(typedObj, offset + 4);
-    var s5 = Load_int8(typedObj, offset + 5);
-    var s6 = Load_int8(typedObj, offset + 6);
-    var s7 = Load_int8(typedObj, offset + 7);
-    var s8 = Load_int8(typedObj, offset + 8);
-    var s9 = Load_int8(typedObj, offset + 9);
-    var s10 = Load_int8(typedObj, offset + 10);
-    var s11 = Load_int8(typedObj, offset + 11);
-    var s12 = Load_int8(typedObj, offset + 12);
-    var s13 = Load_int8(typedObj, offset + 13);
-    var s14 = Load_int8(typedObj, offset + 14);
-    var s15 = Load_int8(typedObj, offset + 15);
-    return simdTypeDescr(s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15);
-
-  case JS_SIMDTYPEREPR_BOOL16X8:
-    var s0 = Load_int16(typedObj, offset + 0);
-    var s1 = Load_int16(typedObj, offset + 2);
-    var s2 = Load_int16(typedObj, offset + 4);
-    var s3 = Load_int16(typedObj, offset + 6);
-    var s4 = Load_int16(typedObj, offset + 8);
-    var s5 = Load_int16(typedObj, offset + 10);
-    var s6 = Load_int16(typedObj, offset + 12);
-    var s7 = Load_int16(typedObj, offset + 14);
-    return simdTypeDescr(s0, s1, s2, s3, s4, s5, s6, s7);
-
-  case JS_SIMDTYPEREPR_BOOL32X4:
-    var x = Load_int32(typedObj, offset + 0);
-    var y = Load_int32(typedObj, offset + 4);
-    var z = Load_int32(typedObj, offset + 8);
-    var w = Load_int32(typedObj, offset + 12);
-    return simdTypeDescr(x, y, z, w);
-
-  case JS_SIMDTYPEREPR_BOOL64X2:
-    var x = Load_int32(typedObj, offset + 0);
-    var y = Load_int32(typedObj, offset + 8);
-    return simdTypeDescr(x, y);
-
-  }
-
-  assert(false, "Unhandled SIMD type: " + type);
-  return undefined;
-}
-
 ///////////////////////////////////////////////////////////////////////////
 // Setting values
 //
 // The methods in this section modify the data pointed at by `this`.
 
 // Writes `fromValue` into the `typedObj` at offset `offset`, adapting
 // it to `descr` as needed. This is the most general entry point
 // and works for any type.
@@ -291,20 +150,16 @@ function TypedObjectSet(descr, typedObj,
   case JS_TYPEREPR_SCALAR_KIND:
     TypedObjectSetScalar(descr, typedObj, offset, fromValue);
     return;
 
   case JS_TYPEREPR_REFERENCE_KIND:
     TypedObjectSetReference(descr, typedObj, offset, name, fromValue);
     return;
 
-  case JS_TYPEREPR_SIMD_KIND:
-    TypedObjectSetSimd(descr, typedObj, offset, fromValue);
-    return;
-
   case JS_TYPEREPR_ARRAY_KIND:
     var length = DESCR_ARRAY_LENGTH(descr);
     if (TypedObjectSetArray(descr, length, typedObj, offset, fromValue))
       return;
     break;
 
   case JS_TYPEREPR_STRUCT_KIND:
     if (!IsObject(fromValue))
@@ -409,116 +264,16 @@ function TypedObjectSetReference(descr, 
     return Store_string(typedObj, offset, name, ToString(fromValue));
   }
 
   assert(false, "Unhandled scalar type: " + type);
   return undefined;
 }
 
 // Sets `fromValue` to `this` assuming that `this` is a scalar type.
-function TypedObjectSetSimd(descr, typedObj, offset, fromValue) {
-  if (!IsObject(fromValue) || !ObjectIsTypedObject(fromValue))
-    ThrowTypeError(JSMSG_CANT_CONVERT_TO,
-                   typeof(fromValue),
-                   DESCR_STRING_REPR(descr));
-
-  if (!DescrsEquiv(descr, TypedObjectTypeDescr(fromValue)))
-    ThrowTypeError(JSMSG_CANT_CONVERT_TO,
-                   typeof(fromValue),
-                   DESCR_STRING_REPR(descr));
-
-  var type = DESCR_TYPE(descr);
-  switch (type) {
-    case JS_SIMDTYPEREPR_FLOAT32X4:
-      Store_float32(typedObj, offset + 0, Load_float32(fromValue, 0));
-      Store_float32(typedObj, offset + 4, Load_float32(fromValue, 4));
-      Store_float32(typedObj, offset + 8, Load_float32(fromValue, 8));
-      Store_float32(typedObj, offset + 12, Load_float32(fromValue, 12));
-      break;
-    case JS_SIMDTYPEREPR_FLOAT64X2:
-      Store_float64(typedObj, offset + 0, Load_float64(fromValue, 0));
-      Store_float64(typedObj, offset + 8, Load_float64(fromValue, 8));
-      break;
-    case JS_SIMDTYPEREPR_INT8X16:
-    case JS_SIMDTYPEREPR_BOOL8X16:
-      Store_int8(typedObj, offset + 0, Load_int8(fromValue, 0));
-      Store_int8(typedObj, offset + 1, Load_int8(fromValue, 1));
-      Store_int8(typedObj, offset + 2, Load_int8(fromValue, 2));
-      Store_int8(typedObj, offset + 3, Load_int8(fromValue, 3));
-      Store_int8(typedObj, offset + 4, Load_int8(fromValue, 4));
-      Store_int8(typedObj, offset + 5, Load_int8(fromValue, 5));
-      Store_int8(typedObj, offset + 6, Load_int8(fromValue, 6));
-      Store_int8(typedObj, offset + 7, Load_int8(fromValue, 7));
-      Store_int8(typedObj, offset + 8, Load_int8(fromValue, 8));
-      Store_int8(typedObj, offset + 9, Load_int8(fromValue, 9));
-      Store_int8(typedObj, offset + 10, Load_int8(fromValue, 10));
-      Store_int8(typedObj, offset + 11, Load_int8(fromValue, 11));
-      Store_int8(typedObj, offset + 12, Load_int8(fromValue, 12));
-      Store_int8(typedObj, offset + 13, Load_int8(fromValue, 13));
-      Store_int8(typedObj, offset + 14, Load_int8(fromValue, 14));
-      Store_int8(typedObj, offset + 15, Load_int8(fromValue, 15));
-      break;
-    case JS_SIMDTYPEREPR_INT16X8:
-    case JS_SIMDTYPEREPR_BOOL16X8:
-      Store_int16(typedObj, offset + 0, Load_int16(fromValue, 0));
-      Store_int16(typedObj, offset + 2, Load_int16(fromValue, 2));
-      Store_int16(typedObj, offset + 4, Load_int16(fromValue, 4));
-      Store_int16(typedObj, offset + 6, Load_int16(fromValue, 6));
-      Store_int16(typedObj, offset + 8, Load_int16(fromValue, 8));
-      Store_int16(typedObj, offset + 10, Load_int16(fromValue, 10));
-      Store_int16(typedObj, offset + 12, Load_int16(fromValue, 12));
-      Store_int16(typedObj, offset + 14, Load_int16(fromValue, 14));
-      break;
-    case JS_SIMDTYPEREPR_INT32X4:
-    case JS_SIMDTYPEREPR_BOOL32X4:
-    case JS_SIMDTYPEREPR_BOOL64X2:
-      Store_int32(typedObj, offset + 0, Load_int32(fromValue, 0));
-      Store_int32(typedObj, offset + 4, Load_int32(fromValue, 4));
-      Store_int32(typedObj, offset + 8, Load_int32(fromValue, 8));
-      Store_int32(typedObj, offset + 12, Load_int32(fromValue, 12));
-      break;
-    case JS_SIMDTYPEREPR_UINT8X16:
-      Store_uint8(typedObj, offset + 0, Load_uint8(fromValue, 0));
-      Store_uint8(typedObj, offset + 1, Load_uint8(fromValue, 1));
-      Store_uint8(typedObj, offset + 2, Load_uint8(fromValue, 2));
-      Store_uint8(typedObj, offset + 3, Load_uint8(fromValue, 3));
-      Store_uint8(typedObj, offset + 4, Load_uint8(fromValue, 4));
-      Store_uint8(typedObj, offset + 5, Load_uint8(fromValue, 5));
-      Store_uint8(typedObj, offset + 6, Load_uint8(fromValue, 6));
-      Store_uint8(typedObj, offset + 7, Load_uint8(fromValue, 7));
-      Store_uint8(typedObj, offset + 8, Load_uint8(fromValue, 8));
-      Store_uint8(typedObj, offset + 9, Load_uint8(fromValue, 9));
-      Store_uint8(typedObj, offset + 10, Load_uint8(fromValue, 10));
-      Store_uint8(typedObj, offset + 11, Load_uint8(fromValue, 11));
-      Store_uint8(typedObj, offset + 12, Load_uint8(fromValue, 12));
-      Store_uint8(typedObj, offset + 13, Load_uint8(fromValue, 13));
-      Store_uint8(typedObj, offset + 14, Load_uint8(fromValue, 14));
-      Store_uint8(typedObj, offset + 15, Load_uint8(fromValue, 15));
-      break;
-    case JS_SIMDTYPEREPR_UINT16X8:
-      Store_uint16(typedObj, offset + 0, Load_uint16(fromValue, 0));
-      Store_uint16(typedObj, offset + 2, Load_uint16(fromValue, 2));
-      Store_uint16(typedObj, offset + 4, Load_uint16(fromValue, 4));
-      Store_uint16(typedObj, offset + 6, Load_uint16(fromValue, 6));
-      Store_uint16(typedObj, offset + 8, Load_uint16(fromValue, 8));
-      Store_uint16(typedObj, offset + 10, Load_uint16(fromValue, 10));
-      Store_uint16(typedObj, offset + 12, Load_uint16(fromValue, 12));
-      Store_uint16(typedObj, offset + 14, Load_uint16(fromValue, 14));
-      break;
-    case JS_SIMDTYPEREPR_UINT32X4:
-      Store_uint32(typedObj, offset + 0, Load_uint32(fromValue, 0));
-      Store_uint32(typedObj, offset + 4, Load_uint32(fromValue, 4));
-      Store_uint32(typedObj, offset + 8, Load_uint32(fromValue, 8));
-      Store_uint32(typedObj, offset + 12, Load_uint32(fromValue, 12));
-      break;
-    default:
-      assert(false, "Unhandled Simd type: " + type);
-  }
-}
-
 ///////////////////////////////////////////////////////////////////////////
 // C++ Wrappers
 //
 // These helpers are invoked by C++ code or used as method bodies.
 
 // Wrapper for use from C++ code.
 function ConvertAndCopyTo(destDescr,
                           destTypedObj,
@@ -625,251 +380,16 @@ function TypedObjectArrayRedimension(new
   assert(DESCR_SIZE(oldArrayType) == DESCR_SIZE(newArrayType),
          "Byte sizes should be equal");
 
   // Rewrap the data from `this` in a new type.
   return NewDerivedTypedObject(newArrayType, this, 0);
 }
 
 ///////////////////////////////////////////////////////////////////////////
-// SIMD
-
-function SimdProtoString(type) {
-  switch (type) {
-  case JS_SIMDTYPEREPR_INT8X16:
-    return "Int8x16";
-  case JS_SIMDTYPEREPR_INT16X8:
-    return "Int16x8";
-  case JS_SIMDTYPEREPR_INT32X4:
-    return "Int32x4";
-  case JS_SIMDTYPEREPR_UINT8X16:
-    return "Uint8x16";
-  case JS_SIMDTYPEREPR_UINT16X8:
-    return "Uint16x8";
-  case JS_SIMDTYPEREPR_UINT32X4:
-    return "Uint32x4";
-  case JS_SIMDTYPEREPR_FLOAT32X4:
-    return "Float32x4";
-  case JS_SIMDTYPEREPR_FLOAT64X2:
-    return "Float64x2";
-  case JS_SIMDTYPEREPR_BOOL8X16:
-    return "Bool8x16";
-  case JS_SIMDTYPEREPR_BOOL16X8:
-    return "Bool16x8";
-  case JS_SIMDTYPEREPR_BOOL32X4:
-    return "Bool32x4";
-  case JS_SIMDTYPEREPR_BOOL64X2:
-    return "Bool64x2";
-  }
-
-  assert(false, "Unhandled type constant");
-  return undefined;
-}
-
-function SimdTypeToLength(type) {
-  switch (type) {
-  case JS_SIMDTYPEREPR_INT8X16:
-  case JS_SIMDTYPEREPR_BOOL8X16:
-    return 16;
-  case JS_SIMDTYPEREPR_INT16X8:
-  case JS_SIMDTYPEREPR_BOOL16X8:
-    return 8;
-  case JS_SIMDTYPEREPR_INT32X4:
-  case JS_SIMDTYPEREPR_FLOAT32X4:
-  case JS_SIMDTYPEREPR_BOOL32X4:
-    return 4;
-  case JS_SIMDTYPEREPR_FLOAT64X2:
-  case JS_SIMDTYPEREPR_BOOL64X2:
-    return 2;
-  }
-
-  assert(false, "Unhandled type constant");
-  return undefined;
-}
-
-// This implements SIMD.*.prototype.valueOf().
-// Once we have proper value semantics for SIMD types, this function should just
-// perform a type check and return this.
-// For now, throw a TypeError unconditionally since valueOf() was probably
-// called from ToNumber() which is supposed to throw when attempting to convert
-// a SIMD value to a number.
-function SimdValueOf() {
-  if (!IsObject(this) || !ObjectIsTypedObject(this))
-    ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "SIMD", "valueOf", typeof this);
-
-  var descr = TypedObjectTypeDescr(this);
-
-  if (DESCR_KIND(descr) != JS_TYPEREPR_SIMD_KIND)
-    ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "SIMD", "valueOf", typeof this);
-
-  ThrowTypeError(JSMSG_SIMD_TO_NUMBER);
-}
-
-function SimdToSource() {
-  if (!IsObject(this) || !ObjectIsTypedObject(this))
-    ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "SIMD.*", "toSource", typeof this);
-
-  var descr = TypedObjectTypeDescr(this);
-
-  if (DESCR_KIND(descr) != JS_TYPEREPR_SIMD_KIND)
-    ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "SIMD.*", "toSource", typeof this);
-
-  return SimdFormatString(descr, this);
-}
-
-function SimdToString() {
-  if (!IsObject(this) || !ObjectIsTypedObject(this))
-    ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "SIMD.*", "toString", typeof this);
-
-  var descr = TypedObjectTypeDescr(this);
-
-  if (DESCR_KIND(descr) != JS_TYPEREPR_SIMD_KIND)
-    ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "SIMD.*", "toString", typeof this);
-
-  return SimdFormatString(descr, this);
-}
-
-function SimdFormatString(descr, typedObj) {
-  var typerepr = DESCR_TYPE(descr);
-  var protoString = SimdProtoString(typerepr);
-  switch (typerepr) {
-      case JS_SIMDTYPEREPR_INT8X16: {
-          var s1 = callFunction(std_SIMD_Int8x16_extractLane, null, typedObj, 0);
-          var s2 = callFunction(std_SIMD_Int8x16_extractLane, null, typedObj, 1);
-          var s3 = callFunction(std_SIMD_Int8x16_extractLane, null, typedObj, 2);
-          var s4 = callFunction(std_SIMD_Int8x16_extractLane, null, typedObj, 3);
-          var s5 = callFunction(std_SIMD_Int8x16_extractLane, null, typedObj, 4);
-          var s6 = callFunction(std_SIMD_Int8x16_extractLane, null, typedObj, 5);
-          var s7 = callFunction(std_SIMD_Int8x16_extractLane, null, typedObj, 6);
-          var s8 = callFunction(std_SIMD_Int8x16_extractLane, null, typedObj, 7);
-          var s9 = callFunction(std_SIMD_Int8x16_extractLane, null, typedObj, 8);
-          var s10 = callFunction(std_SIMD_Int8x16_extractLane, null, typedObj, 9);
-          var s11 = callFunction(std_SIMD_Int8x16_extractLane, null, typedObj, 10);
-          var s12 = callFunction(std_SIMD_Int8x16_extractLane, null, typedObj, 11);
-          var s13 = callFunction(std_SIMD_Int8x16_extractLane, null, typedObj, 12);
-          var s14 = callFunction(std_SIMD_Int8x16_extractLane, null, typedObj, 13);
-          var s15 = callFunction(std_SIMD_Int8x16_extractLane, null, typedObj, 14);
-          var s16 = callFunction(std_SIMD_Int8x16_extractLane, null, typedObj, 15);
-          return `SIMD.${protoString}(${s1}, ${s2}, ${s3}, ${s4}, ${s5}, ${s6}, ${s7}, ${s8}, ${s9}, ${s10}, ${s11}, ${s12}, ${s13}, ${s14}, ${s15}, ${s16})`;
-      }
-      case JS_SIMDTYPEREPR_INT16X8: {
-          var s1 = callFunction(std_SIMD_Int16x8_extractLane, null, typedObj, 0);
-          var s2 = callFunction(std_SIMD_Int16x8_extractLane, null, typedObj, 1);
-          var s3 = callFunction(std_SIMD_Int16x8_extractLane, null, typedObj, 2);
-          var s4 = callFunction(std_SIMD_Int16x8_extractLane, null, typedObj, 3);
-          var s5 = callFunction(std_SIMD_Int16x8_extractLane, null, typedObj, 4);
-          var s6 = callFunction(std_SIMD_Int16x8_extractLane, null, typedObj, 5);
-          var s7 = callFunction(std_SIMD_Int16x8_extractLane, null, typedObj, 6);
-          var s8 = callFunction(std_SIMD_Int16x8_extractLane, null, typedObj, 7);
-          return `SIMD.${protoString}(${s1}, ${s2}, ${s3}, ${s4}, ${s5}, ${s6}, ${s7}, ${s8})`;
-      }
-      case JS_SIMDTYPEREPR_INT32X4: {
-          var x = callFunction(std_SIMD_Int32x4_extractLane, null, typedObj, 0);
-          var y = callFunction(std_SIMD_Int32x4_extractLane, null, typedObj, 1);
-          var z = callFunction(std_SIMD_Int32x4_extractLane, null, typedObj, 2);
-          var w = callFunction(std_SIMD_Int32x4_extractLane, null, typedObj, 3);
-          return `SIMD.${protoString}(${x}, ${y}, ${z}, ${w})`;
-      }
-      case JS_SIMDTYPEREPR_UINT8X16: {
-          var s1 = callFunction(std_SIMD_Uint8x16_extractLane, null, typedObj, 0);
-          var s2 = callFunction(std_SIMD_Uint8x16_extractLane, null, typedObj, 1);
-          var s3 = callFunction(std_SIMD_Uint8x16_extractLane, null, typedObj, 2);
-          var s4 = callFunction(std_SIMD_Uint8x16_extractLane, null, typedObj, 3);
-          var s5 = callFunction(std_SIMD_Uint8x16_extractLane, null, typedObj, 4);
-          var s6 = callFunction(std_SIMD_Uint8x16_extractLane, null, typedObj, 5);
-          var s7 = callFunction(std_SIMD_Uint8x16_extractLane, null, typedObj, 6);
-          var s8 = callFunction(std_SIMD_Uint8x16_extractLane, null, typedObj, 7);
-          var s9 = callFunction(std_SIMD_Uint8x16_extractLane, null, typedObj, 8);
-          var s10 = callFunction(std_SIMD_Uint8x16_extractLane, null, typedObj, 9);
-          var s11 = callFunction(std_SIMD_Uint8x16_extractLane, null, typedObj, 10);
-          var s12 = callFunction(std_SIMD_Uint8x16_extractLane, null, typedObj, 11);
-          var s13 = callFunction(std_SIMD_Uint8x16_extractLane, null, typedObj, 12);
-          var s14 = callFunction(std_SIMD_Uint8x16_extractLane, null, typedObj, 13);
-          var s15 = callFunction(std_SIMD_Uint8x16_extractLane, null, typedObj, 14);
-          var s16 = callFunction(std_SIMD_Uint8x16_extractLane, null, typedObj, 15);
-          return `SIMD.${protoString}(${s1}, ${s2}, ${s3}, ${s4}, ${s5}, ${s6}, ${s7}, ${s8}, ${s9}, ${s10}, ${s11}, ${s12}, ${s13}, ${s14}, ${s15}, ${s16})`;
-      }
-      case JS_SIMDTYPEREPR_UINT16X8: {
-          var s1 = callFunction(std_SIMD_Uint16x8_extractLane, null, typedObj, 0);
-          var s2 = callFunction(std_SIMD_Uint16x8_extractLane, null, typedObj, 1);
-          var s3 = callFunction(std_SIMD_Uint16x8_extractLane, null, typedObj, 2);
-          var s4 = callFunction(std_SIMD_Uint16x8_extractLane, null, typedObj, 3);
-          var s5 = callFunction(std_SIMD_Uint16x8_extractLane, null, typedObj, 4);
-          var s6 = callFunction(std_SIMD_Uint16x8_extractLane, null, typedObj, 5);
-          var s7 = callFunction(std_SIMD_Uint16x8_extractLane, null, typedObj, 6);
-          var s8 = callFunction(std_SIMD_Uint16x8_extractLane, null, typedObj, 7);
-          return `SIMD.${protoString}(${s1}, ${s2}, ${s3}, ${s4}, ${s5}, ${s6}, ${s7}, ${s8})`;
-      }
-      case JS_SIMDTYPEREPR_UINT32X4: {
-          var x = callFunction(std_SIMD_Uint32x4_extractLane, null, typedObj, 0);
-          var y = callFunction(std_SIMD_Uint32x4_extractLane, null, typedObj, 1);
-          var z = callFunction(std_SIMD_Uint32x4_extractLane, null, typedObj, 2);
-          var w = callFunction(std_SIMD_Uint32x4_extractLane, null, typedObj, 3);
-          return `SIMD.${protoString}(${x}, ${y}, ${z}, ${w})`;
-      }
-      case JS_SIMDTYPEREPR_FLOAT32X4: {
-          var x = callFunction(std_SIMD_Float32x4_extractLane, null, typedObj, 0);
-          var y = callFunction(std_SIMD_Float32x4_extractLane, null, typedObj, 1);
-          var z = callFunction(std_SIMD_Float32x4_extractLane, null, typedObj, 2);
-          var w = callFunction(std_SIMD_Float32x4_extractLane, null, typedObj, 3);
-          return `SIMD.${protoString}(${x}, ${y}, ${z}, ${w})`;
-      }
-      case JS_SIMDTYPEREPR_FLOAT64X2: {
-          var x = callFunction(std_SIMD_Float64x2_extractLane, null, typedObj, 0);
-          var y = callFunction(std_SIMD_Float64x2_extractLane, null, typedObj, 1);
-          return `SIMD.${protoString}(${x}, ${y})`;
-      }
-      case JS_SIMDTYPEREPR_BOOL8X16: {
-          var s1 = callFunction(std_SIMD_Bool8x16_extractLane, null, typedObj, 0);
-          var s2 = callFunction(std_SIMD_Bool8x16_extractLane, null, typedObj, 1);
-          var s3 = callFunction(std_SIMD_Bool8x16_extractLane, null, typedObj, 2);
-          var s4 = callFunction(std_SIMD_Bool8x16_extractLane, null, typedObj, 3);
-          var s5 = callFunction(std_SIMD_Bool8x16_extractLane, null, typedObj, 4);
-          var s6 = callFunction(std_SIMD_Bool8x16_extractLane, null, typedObj, 5);
-          var s7 = callFunction(std_SIMD_Bool8x16_extractLane, null, typedObj, 6);
-          var s8 = callFunction(std_SIMD_Bool8x16_extractLane, null, typedObj, 7);
-          var s9 = callFunction(std_SIMD_Bool8x16_extractLane, null, typedObj, 8);
-          var s10 = callFunction(std_SIMD_Bool8x16_extractLane, null, typedObj, 9);
-          var s11 = callFunction(std_SIMD_Bool8x16_extractLane, null, typedObj, 10);
-          var s12 = callFunction(std_SIMD_Bool8x16_extractLane, null, typedObj, 11);
-          var s13 = callFunction(std_SIMD_Bool8x16_extractLane, null, typedObj, 12);
-          var s14 = callFunction(std_SIMD_Bool8x16_extractLane, null, typedObj, 13);
-          var s15 = callFunction(std_SIMD_Bool8x16_extractLane, null, typedObj, 14);
-          var s16 = callFunction(std_SIMD_Bool8x16_extractLane, null, typedObj, 15);
-          return `SIMD.${protoString}(${s1}, ${s2}, ${s3}, ${s4}, ${s5}, ${s6}, ${s7}, ${s8}, ${s9}, ${s10}, ${s11}, ${s12}, ${s13}, ${s14}, ${s15}, ${s16})`;
-      }
-      case JS_SIMDTYPEREPR_BOOL16X8: {
-          var s1 = callFunction(std_SIMD_Bool16x8_extractLane, null, typedObj, 0);
-          var s2 = callFunction(std_SIMD_Bool16x8_extractLane, null, typedObj, 1);
-          var s3 = callFunction(std_SIMD_Bool16x8_extractLane, null, typedObj, 2);
-          var s4 = callFunction(std_SIMD_Bool16x8_extractLane, null, typedObj, 3);
-          var s5 = callFunction(std_SIMD_Bool16x8_extractLane, null, typedObj, 4);
-          var s6 = callFunction(std_SIMD_Bool16x8_extractLane, null, typedObj, 5);
-          var s7 = callFunction(std_SIMD_Bool16x8_extractLane, null, typedObj, 6);
-          var s8 = callFunction(std_SIMD_Bool16x8_extractLane, null, typedObj, 7);
-          return `SIMD.${protoString}(${s1}, ${s2}, ${s3}, ${s4}, ${s5}, ${s6}, ${s7}, ${s8})`;
-      }
-      case JS_SIMDTYPEREPR_BOOL32X4: {
-          var x = callFunction(std_SIMD_Bool32x4_extractLane, null, typedObj, 0);
-          var y = callFunction(std_SIMD_Bool32x4_extractLane, null, typedObj, 1);
-          var z = callFunction(std_SIMD_Bool32x4_extractLane, null, typedObj, 2);
-          var w = callFunction(std_SIMD_Bool32x4_extractLane, null, typedObj, 3);
-          return `SIMD.${protoString}(${x}, ${y}, ${z}, ${w})`;
-      }
-      case JS_SIMDTYPEREPR_BOOL64X2: {
-          var x = callFunction(std_SIMD_Bool64x2_extractLane, null, typedObj, 0);
-          var y = callFunction(std_SIMD_Bool64x2_extractLane, null, typedObj, 1);
-          return `SIMD.${protoString}(${x}, ${y})`;
-      }
-  }
-  assert(false, "unexpected SIMD kind");
-  return "?";
-}
-
-///////////////////////////////////////////////////////////////////////////
 // Miscellaneous
 
 function DescrsEquiv(descr1, descr2) {
   assert(IsObject(descr1) && ObjectIsTypeDescr(descr1), "descr1 not descr");
   assert(IsObject(descr2) && ObjectIsTypeDescr(descr2), "descr2 not descr");
 
   // Potential optimization: these two strings are guaranteed to be
   // atoms, and hence this string comparison can just be a pointer
--- a/js/src/builtin/TypedObjectConstants.h
+++ b/js/src/builtin/TypedObjectConstants.h
@@ -48,17 +48,17 @@
 #define JS_DESCR_SLOT_STRING_REPR        1  // Atomized string representation
 #define JS_DESCR_SLOT_ALIGNMENT          2  // Alignment in bytes
 #define JS_DESCR_SLOT_SIZE               3  // Size in bytes, else 0
 #define JS_DESCR_SLOT_OPAQUE             4  // Atomized string representation
 #define JS_DESCR_SLOT_TYPROTO            5  // Prototype for instances, if any
 #define JS_DESCR_SLOT_ARRAYPROTO         6  // Lazily created prototype for arrays
 #define JS_DESCR_SLOT_TRACE_LIST         7  // List of references for use in tracing
 
-// Slots on scalars, references, and SIMD objects
+// Slots on scalars, references
 #define JS_DESCR_SLOT_TYPE               8  // Type code
 
 // Slots on array descriptors
 #define JS_DESCR_SLOT_ARRAY_ELEM_TYPE    8
 #define JS_DESCR_SLOT_ARRAY_LENGTH       9
 
 // Slots on struct type objects
 #define JS_DESCR_SLOT_STRUCT_FIELD_NAMES 8
@@ -70,52 +70,31 @@
 
 // These constants are for use exclusively in JS code. In C++ code,
 // prefer TypeRepresentation::Scalar etc, which allows you to
 // write a switch which will receive a warning if you omit a case.
 #define JS_TYPEREPR_SCALAR_KIND         1
 #define JS_TYPEREPR_REFERENCE_KIND      2
 #define JS_TYPEREPR_STRUCT_KIND         3
 #define JS_TYPEREPR_ARRAY_KIND          4
-#define JS_TYPEREPR_SIMD_KIND           5
 
 // These constants are for use exclusively in JS code. In C++ code,
 // prefer Scalar::Int8 etc, which allows you to write a switch which will
 // receive a warning if you omit a case.
 #define JS_SCALARTYPEREPR_INT8          0
 #define JS_SCALARTYPEREPR_UINT8         1
 #define JS_SCALARTYPEREPR_INT16         2
 #define JS_SCALARTYPEREPR_UINT16        3
 #define JS_SCALARTYPEREPR_INT32         4
 #define JS_SCALARTYPEREPR_UINT32        5
 #define JS_SCALARTYPEREPR_FLOAT32       6
 #define JS_SCALARTYPEREPR_FLOAT64       7
 #define JS_SCALARTYPEREPR_UINT8_CLAMPED 8
-#define JS_SCALARTYPEREPR_FLOAT32X4     11
-#define JS_SCALARTYPEREPR_INT8X16       12
-#define JS_SCALARTYPEREPR_INT16X8       13
-#define JS_SCALARTYPEREPR_INT32X4       14
 
 // These constants are for use exclusively in JS code. In C++ code,
 // prefer ReferenceTypeRepresentation::TYPE_ANY etc, which allows
 // you to write a switch which will receive a warning if you omit a
 // case.
 #define JS_REFERENCETYPEREPR_ANY        0
 #define JS_REFERENCETYPEREPR_OBJECT     1
 #define JS_REFERENCETYPEREPR_STRING     2
 
-// These constants are for use exclusively in JS code. In C++ code, prefer
-// SimdType::Int32x4 etc, since that allows you to write a switch which will
-// receive a warning if you omit a case.
-#define JS_SIMDTYPEREPR_INT8X16         0
-#define JS_SIMDTYPEREPR_INT16X8         1
-#define JS_SIMDTYPEREPR_INT32X4         2
-#define JS_SIMDTYPEREPR_UINT8X16        3
-#define JS_SIMDTYPEREPR_UINT16X8        4
-#define JS_SIMDTYPEREPR_UINT32X4        5
-#define JS_SIMDTYPEREPR_FLOAT32X4       6
-#define JS_SIMDTYPEREPR_FLOAT64X2       7
-#define JS_SIMDTYPEREPR_BOOL8X16        8
-#define JS_SIMDTYPEREPR_BOOL16X8        9
-#define JS_SIMDTYPEREPR_BOOL32X4       10
-#define JS_SIMDTYPEREPR_BOOL64X2       11
-
 #endif
--- a/js/src/devtools/automation/cgc-jittest-timeouts.txt
+++ b/js/src/devtools/automation/cgc-jittest-timeouts.txt
@@ -1,9 +1,8 @@
-SIMD/nursery-overflow.js
 asm.js/testBug1117235.js
 asm.js/testParallelCompile.js
 auto-regress/bug653395.js
 auto-regress/bug654392.js
 auto-regress/bug675251.js
 auto-regress/bug729797.js
 baseline/bug847446.js
 baseline/bug852175.js
--- a/js/src/doc/JITOptimizations/Outcomes.md
+++ b/js/src/doc/JITOptimizations/Outcomes.md
@@ -147,21 +147,16 @@ Arrays at this element access location h
 The storage for the typed object being accessed at this location might be a detached ArrayBuffer.  (This can happen if the typed object, or its underlying buffer as accessed using `TypedObject.storage(typedObject).buffer`, is transferred using the structured clone algorithm.)
 
 ### TypedObjectArrayRange
 
 Failed to do range check of element access on a typed object.
 
 ### AccessNotDense
 
-### AccessNotSimdObject
-
-The observed type of the target of the property access doesn't guarantee
-that it is a SIMD object.
-
 ### AccessNotTypedObject
 
 The observed type of the target of the property access doesn't guarantee
 that it is a TypedObject.
 
 ### AccessNotTypedArray
 
 The observed type of the target of the property access doesn't guarantee
@@ -217,25 +212,16 @@ target values which may be non-native ob
 IonMonkey does not generate inline caches for element reads in which
 the keys have never been observed to be a String, Symbol, or Int32.
 
 ### SetElemNonDenseNonTANotCached
 
 IonMonkey only generates inline caches for element accesses which are
 either on dense objects (e.g. dense Arrays), or Typed Arrays.
 
-### NoSimdJitSupport
-
-Optimization failed because SIMD JIT support was not enabled.
-
-### SimdTypeNotOptimized
-
-The type observed as being retrieved from this property access did not
-match an optimizable type.
-
 ### HasCommonInliningPath
 
 Inlining was abandoned because the inlining call path was repeated.  A
 repeated call path is indicative of a potentially mutually recursive
 function call chain.
 
 ### Inlined
 
--- a/js/src/frontend/BinToken.h
+++ b/js/src/frontend/BinToken.h
@@ -269,17 +269,17 @@ const size_t BINKIND_LIMIT = 183;
  * ```c++
  * #define WITH_VARIANT(CPP_NAME, SPEC_NAME) ...
  * FOR_EACH_BIN_VARIANT(WITH_VARIANT)
  * ```
  *
  * (sorted by alphabetical order)
  */
 #define FOR_EACH_BIN_FIELD(F) \
-    F(Offset, "_offset") \
+    F(Skip, "_skip") \
     F(Alternate, "alternate") \
     F(Arguments, "arguments") \
     F(Binding, "binding") \
     F(BindingScope, "bindingScope") \
     F(Body, "body") \
     F(BodyScope, "bodyScope") \
     F(Callee, "callee") \
     F(CapturedNames, "capturedNames") \
--- a/js/src/frontend/TokenStream.cpp
+++ b/js/src/frontend/TokenStream.cpp
@@ -7,24 +7,27 @@
 // JS lexical scanner.
 
 #include "frontend/TokenStream.h"
 
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/IntegerTypeTraits.h"
 #include "mozilla/Likely.h"
+#include "mozilla/Maybe.h"
 #include "mozilla/MemoryChecking.h"
 #include "mozilla/ScopeExit.h"
+#include "mozilla/Span.h"
 #include "mozilla/TextUtils.h"
 #include "mozilla/Utf8.h"
 
 #include <algorithm>
 #include <ctype.h>
 #include <stdarg.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <string.h>
 #include <utility>
 
 #include "jsexn.h"
 #include "jsnum.h"
 
 #include "frontend/BytecodeCompiler.h"
@@ -36,20 +39,24 @@
 #include "util/Unicode.h"
 #include "vm/HelperThreads.h"
 #include "vm/JSAtom.h"
 #include "vm/JSContext.h"
 #include "vm/Realm.h"
 
 using mozilla::ArrayLength;
 using mozilla::AssertedCast;
+using mozilla::DecodeOneUtf8CodePoint;
 using mozilla::IsAscii;
 using mozilla::IsAsciiAlpha;
 using mozilla::IsAsciiDigit;
+using mozilla::IsTrailingUnit;
 using mozilla::MakeScopeExit;
+using mozilla::MakeSpan;
+using mozilla::Maybe;
 using mozilla::PointerRangeSize;
 using mozilla::Utf8Unit;
 
 struct ReservedWordInfo
 {
     const char* chars;         // C string with reserved word text
     js::frontend::TokenKind tokentype;
 };
@@ -459,16 +466,51 @@ TokenStreamCharsBase<char16_t>::fillChar
         if (!this->charBuffer.append(ch))
             return false;
     }
 
     MOZ_ASSERT(cur == end);
     return true;
 }
 
+template<>
+MOZ_MUST_USE bool
+TokenStreamCharsBase<Utf8Unit>::fillCharBufferFromSourceNormalizingAsciiLineBreaks(const Utf8Unit* cur,
+                                                                                   const Utf8Unit* end)
+{
+    MOZ_ASSERT(this->charBuffer.length() == 0);
+
+    while (cur < end) {
+        Utf8Unit unit = *cur++;
+        if (MOZ_LIKELY(IsAscii(unit))) {
+            char16_t ch = unit.toUint8();
+            if (ch == '\r') {
+                ch = '\n';
+                if (cur < end && *cur == Utf8Unit('\n'))
+                    cur++;
+            }
+
+            if (!this->charBuffer.append(ch))
+                return false;
+
+            continue;
+        }
+
+        Maybe<char32_t> ch = DecodeOneUtf8CodePoint(unit, &cur, end);
+        MOZ_ASSERT(ch.isSome(),
+                   "provided source text should already have been validated");
+
+        if (!appendCodePointToCharBuffer(ch.value()))
+            return false;
+    }
+
+    MOZ_ASSERT(cur == end);
+    return true;
+}
+
 template<typename CharT, class AnyCharsAccess>
 TokenStreamSpecific<CharT, AnyCharsAccess>::TokenStreamSpecific(JSContext* cx,
                                                                 const ReadOnlyCompileOptions& options,
                                                                 const CharT* base, size_t length)
   : TokenStreamChars<CharT, AnyCharsAccess>(cx, base, length, options.scriptSourceOffset)
 {}
 
 bool
@@ -506,51 +548,251 @@ void
 TokenStreamAnyChars::undoInternalUpdateLineInfoForEOL()
 {
     MOZ_ASSERT(prevLinebase != size_t(-1)); // we should never get more than one EOL
     linebase = prevLinebase;
     prevLinebase = size_t(-1);
     lineno--;
 }
 
-template<class AnyCharsAccess>
-bool
-TokenStreamChars<char16_t, AnyCharsAccess>::getCodePoint(int32_t* cp)
+#ifdef DEBUG
+
+template<>
+inline void
+SourceUnits<char16_t>::assertNextCodePoint(const PeekedCodePoint<char16_t>& peeked)
+{
+    char32_t c = peeked.codePoint();
+    if (c < unicode::NonBMPMin) {
+        MOZ_ASSERT(peeked.lengthInUnits() == 1);
+        MOZ_ASSERT(ptr[0] == c);
+    } else {
+        MOZ_ASSERT(peeked.lengthInUnits() == 2);
+        char16_t lead, trail;
+        unicode::UTF16Encode(c, &lead, &trail);
+        MOZ_ASSERT(ptr[0] == lead);
+        MOZ_ASSERT(ptr[1] == trail);
+    }
+}
+
+template<>
+inline void
+SourceUnits<Utf8Unit>::assertNextCodePoint(const PeekedCodePoint<Utf8Unit>& peeked)
 {
-    TokenStreamAnyChars& anyChars = anyCharsAccess();
-
-    if (MOZ_UNLIKELY(this->sourceUnits.atEnd())) {
-        anyChars.flags.isEOF = true;
-        *cp = EOF;
-        return true;
+    char32_t c = peeked.codePoint();
+
+    // This is all roughly indulgence of paranoia only for assertions, so the
+    // reimplementation of UTF-8 encoding a code point is (we think) a virtue.
+    uint8_t expectedUnits[4] = {};
+    if (c < 0x80) {
+        expectedUnits[0] = AssertedCast<uint8_t>(c);
+    } else if (c < 0x800) {
+        expectedUnits[0] = 0b1100'0000 | (c >> 6);
+        expectedUnits[1] = 0b1000'0000 | (c & 0b11'1111);
+    } else if (c < 0x10000) {
+        expectedUnits[0] = 0b1110'0000 | (c >> 12);
+        expectedUnits[1] = 0b1000'0000 | ((c >> 6) & 0b11'1111);
+        expectedUnits[2] = 0b1000'0000 | (c & 0b11'1111);
+    } else {
+        expectedUnits[0] = 0b1110'0000 | (c >> 18);
+        expectedUnits[2] = 0b1000'0000 | ((c >> 12) & 0b11'1111);
+        expectedUnits[2] = 0b1000'0000 | ((c >> 6) & 0b11'1111);
+        expectedUnits[3] = 0b1000'0000 | (c & 0b11'1111);
     }
 
-    int32_t c = this->sourceUnits.getCodeUnit();
+    MOZ_ASSERT(peeked.lengthInUnits() <= 4);
+    for (uint8_t i = 0; i < peeked.lengthInUnits(); i++)
+        MOZ_ASSERT(expectedUnits[i] == ptr[i].toUint8());
+}
+
+#endif // DEBUG
+
+template<class AnyCharsAccess>
+MOZ_COLD void
+TokenStreamChars<Utf8Unit, AnyCharsAccess>::internalEncodingError(uint8_t relevantUnits,
+                                                                  unsigned errorNumber, ...)
+{
+    va_list args;
+    va_start(args, errorNumber);
 
     do {
-        // Normalize the char16_t if it was a newline.
-        if (MOZ_UNLIKELY(c == '\n'))
+        size_t offset = this->sourceUnits.offset();
+
+        ErrorMetadata err;
+
+        TokenStreamAnyChars& anyChars = anyCharsAccess();
+
+        if (bool hasLineOfContext = anyChars.fillExcludingContext(&err, offset)) {
+            if (!internalComputeLineOfContext(&err, offset))
+                break;
+
+            // As this is an encoding error, the computed window-end must be
+            // identical to the location of the error -- any further on and the
+            // window would contain invalid Unicode.
+            MOZ_ASSERT_IF(err.lineOfContext != nullptr,
+                          err.lineLength == err.tokenOffset);
+        }
+
+        auto notes = MakeUnique<JSErrorNotes>();
+        if (!notes) {
+            ReportOutOfMemory(anyChars.cx);
             break;
-
-        if (MOZ_UNLIKELY(c == '\r')) {
-            matchLineTerminator('\n');
+        }
+
+        // The largest encoding of a UTF-8 code point is 4 units.  (Encoding an
+        // obsolete 5- or 6-byte code point will complain only about a bad lead
+        // code unit.)
+        constexpr size_t MaxWidth = sizeof("0xHH 0xHH 0xHH 0xHH");
+
+        MOZ_ASSERT(relevantUnits > 0);
+
+        char badUnitsStr[MaxWidth];
+        char* ptr = badUnitsStr;
+        while (relevantUnits > 0) {
+            byteToString(this->sourceUnits.getCodeUnit().toUint8(), ptr);
+            ptr[4] = ' ';
+
+            ptr += 5;
+            relevantUnits--;
+        }
+
+        ptr[-1] = '\0';
+
+        uint32_t line, column;
+        anyChars.srcCoords.lineNumAndColumnIndex(offset, &line, &column);
+
+        if (!notes->addNoteASCII(anyChars.cx, anyChars.getFilename(), line, column,
+                                 GetErrorMessage, nullptr, JSMSG_BAD_CODE_UNITS, badUnitsStr))
+        {
             break;
         }
 
-        if (MOZ_UNLIKELY(c == unicode::LINE_SEPARATOR || c == unicode::PARA_SEPARATOR))
-            break;
-
-        *cp = c;
-        return true;
+        ReportCompileError(anyChars.cx, std::move(err), std::move(notes), JSREPORT_ERROR,
+                           errorNumber, args);
     } while (false);
 
-    if (!updateLineInfoForEOL())
+    va_end(args);
+}
+
+template<class AnyCharsAccess>
+MOZ_COLD void
+TokenStreamChars<Utf8Unit, AnyCharsAccess>::badLeadUnit(Utf8Unit lead)
+{
+    uint8_t leadValue = lead.toUint8();
+
+    char leadByteStr[5];
+    byteToTerminatedString(leadValue, leadByteStr);
+
+    internalEncodingError(1, JSMSG_BAD_LEADING_UTF8_UNIT, leadByteStr);
+}
+
+template<class AnyCharsAccess>
+MOZ_COLD void
+TokenStreamChars<Utf8Unit, AnyCharsAccess>::notEnoughUnits(Utf8Unit lead,
+                                                           uint8_t remaining, uint8_t required)
+{
+    uint8_t leadValue = lead.toUint8();
+
+    MOZ_ASSERT(required == 2 || required == 3 || required == 4);
+    MOZ_ASSERT(remaining < 4);
+    MOZ_ASSERT(remaining < required);
+
+    char leadByteStr[5];
+    byteToTerminatedString(leadValue, leadByteStr);
+
+    // |toHexChar| produces the desired decimal numbers for values < 4.
+    const char expectedStr[] = { toHexChar(required - 1), '\0' };
+    const char actualStr[] = { toHexChar(remaining - 1), '\0' };
+
+    internalEncodingError(remaining, JSMSG_NOT_ENOUGH_CODE_UNITS,
+                          leadByteStr, expectedStr, actualStr, remaining == 2 ? " was" : "s were");
+}
+
+template<class AnyCharsAccess>
+MOZ_COLD void
+TokenStreamChars<Utf8Unit, AnyCharsAccess>::badTrailingUnit(Utf8Unit badUnit,
+                                                            uint8_t unitsObserved)
+{
+    char badByteStr[5];
+    byteToTerminatedString(badUnit.toUint8(), badByteStr);
+
+    internalEncodingError(unitsObserved, JSMSG_BAD_TRAILING_UTF8_UNIT, badByteStr);
+}
+
+template<class AnyCharsAccess>
+MOZ_COLD void
+TokenStreamChars<Utf8Unit, AnyCharsAccess>::badStructurallyValidCodePoint(uint32_t codePoint,
+                                                                          uint8_t codePointLength,
+                                                                          const char* reason)
+{
+    // Construct a string like "0x203D" (including null terminator) to include
+    // in the error message.  Write the string end-to-start from end to start
+    // of an adequately sized |char| array, shifting least significant nibbles
+    // off the number and writing the corresponding hex digits until done, then
+    // prefixing with "0x".  |codePointStr| points at the incrementally
+    // computed string, within |codePointCharsArray|'s bounds.
+
+    // 0x1F'FFFF is the maximum value that can fit in 3+6+6+6 unconstrained
+    // bits in a four-byte UTF-8 code unit sequence.
+    constexpr size_t MaxHexSize = sizeof("0x1F" "FFFF"); // including '\0'
+    char codePointCharsArray[MaxHexSize];
+
+    char* codePointStr = codePointCharsArray + ArrayLength(codePointCharsArray);
+    *--codePointStr = '\0';
+
+    uint32_t copy = codePoint;
+    while (copy) {
+        MOZ_ASSERT(codePointCharsArray < codePointStr);
+        *--codePointStr = toHexChar(copy & 0xF);
+        copy >>= 4;
+    }
+
+    MOZ_ASSERT(codePointCharsArray + 2 <= codePointStr);
+    *--codePointStr = 'x';
+    *--codePointStr = '0';
+
+    internalEncodingError(codePointLength, JSMSG_FORBIDDEN_UTF8_CODE_POINT, codePointStr, reason);
+}
+
+template<class AnyCharsAccess>
+MOZ_MUST_USE bool
+TokenStreamChars<Utf8Unit, AnyCharsAccess>::getNonAsciiCodePointDontNormalize(Utf8Unit lead,
+                                                                              char32_t* codePoint)
+{
+    auto onBadLeadUnit = [this, &lead]() {
+        this->badLeadUnit(lead);
+    };
+
+    auto onNotEnoughUnits = [this, &lead](uint8_t remaining, uint8_t required) {
+        this->notEnoughUnits(lead, remaining, required);
+    };
+
+    auto onBadTrailingUnit = [this, &lead](uint8_t unitsObserved) {
+        this->badTrailingUnit(lead, unitsObserved);
+    };
+
+    auto onBadCodePoint = [this](char32_t badCodePoint, uint8_t unitsObserved) {
+        this->badCodePoint(badCodePoint, unitsObserved);
+    };
+
+    auto onNotShortestForm = [this](char32_t badCodePoint, uint8_t unitsObserved) {
+        this->notShortestForm(badCodePoint, unitsObserved);
+    };
+
+    // If a valid code point is decoded, this function call consumes its code
+    // units.  If not, it ungets the lead code unit and invokes the right error
+    // handler, so on failure we must immediately return false.
+    SourceUnitsIterator iter(this->sourceUnits);
+    Maybe<char32_t> maybeCodePoint =
+        DecodeOneUtf8CodePointInline(lead, &iter, SourceUnitsEnd(),
+                                     onBadLeadUnit, onNotEnoughUnits, onBadTrailingUnit,
+                                     onBadCodePoint, onNotShortestForm);
+    if (maybeCodePoint.isNothing())
         return false;
 
-    *cp = '\n';
+    *codePoint = maybeCodePoint.value();
     return true;
 }
 
 template<class AnyCharsAccess>
 bool
 TokenStreamChars<char16_t, AnyCharsAccess>::getNonAsciiCodePoint(int32_t lead, int32_t* codePoint)
 {
     MOZ_ASSERT(lead != EOF);
@@ -598,35 +840,98 @@ TokenStreamChars<char16_t, AnyCharsAcces
     }
 
     // Otherwise we have a multi-unit code point.
     *codePoint = unicode::UTF16Decode(lead, this->sourceUnits.getCodeUnit());
     MOZ_ASSERT(!IsLineTerminator(AssertedCast<char32_t>(*codePoint)));
     return true;
 }
 
+template<typename CharT, class AnyCharsAccess>
+bool
+TokenStreamSpecific<CharT, AnyCharsAccess>::getCodePoint(int32_t* cp)
+{
+    int32_t unit = getCodeUnit();
+    if (unit == EOF) {
+        MOZ_ASSERT(anyCharsAccess().flags.isEOF,
+                   "flags.isEOF should have been set by getCodeUnit()");
+        *cp = EOF;
+        return true;
+    }
+
+    if (isAsciiCodePoint(unit))
+        return getFullAsciiCodePoint(unit, cp);
+
+    return getNonAsciiCodePoint(unit, cp);
+}
+
 template<class AnyCharsAccess>
-void
-TokenStreamChars<char16_t, AnyCharsAccess>::ungetCodePointIgnoreEOL(uint32_t codePoint)
+bool
+TokenStreamChars<Utf8Unit, AnyCharsAccess>::getNonAsciiCodePoint(int32_t unit, int32_t* codePoint)
 {
-    MOZ_ASSERT(!this->sourceUnits.atStart());
-
-    unsigned numUnits = 0;
-    char16_t units[2];
-    unicode::UTF16Encode(codePoint, units, &numUnits);
-
-    MOZ_ASSERT(numUnits == 1 || numUnits == 2);
-
-    while (numUnits-- > 0)
-        ungetCodeUnit(units[numUnits]);
+    MOZ_ASSERT(unit != EOF);
+    MOZ_ASSERT(!isAsciiCodePoint(unit),
+               "ASCII code unit/point must be handled separately");
+
+    Utf8Unit lead = Utf8Unit(static_cast<unsigned char>(unit));
+    MOZ_ASSERT(lead == this->sourceUnits.previousCodeUnit(),
+               "getNonAsciiCodePoint called incorrectly");
+
+    auto onBadLeadUnit = [this, &lead]() {
+        this->badLeadUnit(lead);
+    };
+
+    auto onNotEnoughUnits = [this, &lead](uint_fast8_t remaining, uint_fast8_t required) {
+        this->notEnoughUnits(lead, remaining, required);
+    };
+
+    auto onBadTrailingUnit = [this, &lead](uint_fast8_t unitsObserved) {
+        this->badTrailingUnit(lead, unitsObserved);
+    };
+
+    auto onBadCodePoint = [this](char32_t badCodePoint, uint_fast8_t unitsObserved) {
+        this->badCodePoint(badCodePoint, unitsObserved);
+    };
+
+    auto onNotShortestForm = [this](char32_t badCodePoint, uint_fast8_t unitsObserved) {
+        this->notShortestForm(badCodePoint, unitsObserved);
+    };
+
+    // This consumes the full, valid code point or ungets |lead| and calls the
+    // appropriate error functor on failure.
+    SourceUnitsIterator iter(this->sourceUnits);
+    Maybe<char32_t> maybeCodePoint =
+        DecodeOneUtf8CodePoint(lead, &iter, SourceUnitsEnd(),
+                               onBadLeadUnit, onNotEnoughUnits, onBadTrailingUnit, onBadCodePoint,
+                               onNotShortestForm);
+    if (maybeCodePoint.isNothing())
+        return false;
+
+    char32_t cp = maybeCodePoint.value();
+    if (MOZ_UNLIKELY(cp == unicode::LINE_SEPARATOR || cp == unicode::PARA_SEPARATOR)) {
+        if (!updateLineInfoForEOL()) {
+#ifdef DEBUG
+            *codePoint = EOF; // sentinel value to hopefully cause errors
+#endif
+            MOZ_MAKE_MEM_UNDEFINED(codePoint, sizeof(*codePoint));
+            return false;
+        }
+
+        *codePoint = '\n';
+    } else {
+        MOZ_ASSERT(!IsLineTerminator(cp));
+        *codePoint = AssertedCast<int32_t>(cp);
+    }
+
+    return true;
 }
 
 template<>
 size_t
-SourceUnits<char16_t>::findWindowStart(size_t offset)
+SourceUnits<char16_t>::findWindowStart(size_t offset) const
 {
     // This is JS's understanding of UTF-16 that allows lone surrogates, so
     // we have to exclude lone surrogates from [windowStart, offset) ourselves.
 
     const char16_t* const earliestPossibleStart = codeUnitPtrAt(startOffset_);
 
     const char16_t* const initial = codeUnitPtrAt(offset);
     const char16_t* p = initial;
@@ -674,17 +979,80 @@ SourceUnits<char16_t>::findWindowStart(s
     }
 
     MOZ_ASSERT(HalfWindowSize() <= WindowRadius);
     return offset - HalfWindowSize();
 }
 
 template<>
 size_t
-SourceUnits<char16_t>::findWindowEnd(size_t offset)
+SourceUnits<Utf8Unit>::findWindowStart(size_t offset) const
+{
+    // |offset| must be the location of the error or somewhere before it, so we
+    // know preceding data is valid UTF-8.
+
+    const Utf8Unit* const earliestPossibleStart = codeUnitPtrAt(startOffset_);
+
+    const Utf8Unit* const initial = codeUnitPtrAt(offset);
+    const Utf8Unit* p = initial;
+
+    auto HalfWindowSize = [&p, &initial]() { return PointerRangeSize(p, initial); };
+
+    while (true) {
+        MOZ_ASSERT(earliestPossibleStart <= p);
+        MOZ_ASSERT(HalfWindowSize() <= WindowRadius);
+        if (p <= earliestPossibleStart || HalfWindowSize() >= WindowRadius)
+            break;
+
+        // Peek backward for a line break, and only decrement if there is none.
+        uint8_t prev = p[-1].toUint8();
+
+        // First check for the ASCII LineTerminators.
+        if (prev == '\r' || prev == '\n')
+            break;
+
+        // Now check for the non-ASCII LineTerminators U+2028 LINE SEPARATOR
+        // (0xE2 0x80 0xA8) and U+2029 PARAGRAPH (0xE2 0x80 0xA9).  If there
+        // aren't three code units available, some comparison here will fail
+        // before we'd underflow.
+        if (MOZ_UNLIKELY((prev == 0xA8 || prev == 0xA9) &&
+                         p[-2].toUint8() == 0x80 &&
+                         p[-3].toUint8() == 0xE2))
+        {
+            break;
+        }
+
+        // Rewind over the non-LineTerminator.  This can't underflow
+        // |earliestPossibleStart| because it begins a code point.
+        while (IsTrailingUnit(*--p))
+            continue;
+
+        MOZ_ASSERT(earliestPossibleStart <= p);
+
+        // But if we underflowed |WindowRadius|, adjust forward and stop.
+        if (HalfWindowSize() > WindowRadius) {
+            static_assert(WindowRadius > 3,
+                          "skipping over non-lead code units below must not "
+                          "advance past |offset|");
+
+            while (IsTrailingUnit(*++p))
+                continue;
+
+            MOZ_ASSERT(HalfWindowSize() < WindowRadius);
+            break;
+        }
+    }
+
+    MOZ_ASSERT(HalfWindowSize() <= WindowRadius);
+    return offset - HalfWindowSize();
+}
+
+template<>
+size_t
+SourceUnits<char16_t>::findWindowEnd(size_t offset) const
 {
     const char16_t* const initial = codeUnitPtrAt(offset);
     const char16_t* p = initial;
 
     auto HalfWindowSize = [&initial, &p]() { return PointerRangeSize(initial, p); };
 
     while (true) {
         MOZ_ASSERT(p <= limit_);
@@ -725,16 +1093,65 @@ SourceUnits<char16_t>::findWindowEnd(siz
         }
 
         p++;
     }
 
     return offset + HalfWindowSize();
 }
 
+template<>
+size_t
+SourceUnits<Utf8Unit>::findWindowEnd(size_t offset) const
+{
+    const Utf8Unit* const initial = codeUnitPtrAt(offset);
+    const Utf8Unit* p = initial;
+
+    auto HalfWindowSize = [&initial, &p]() { return PointerRangeSize(initial, p); };
+
+    while (true) {
+        MOZ_ASSERT(p <= limit_);
+        MOZ_ASSERT(HalfWindowSize() <= WindowRadius);
+        if (p >= limit_ || HalfWindowSize() >= WindowRadius)
+            break;
+
+        // A non-encoding error might be followed by an encoding error within
+        // |maxEnd|, so we must validate as we go to not include invalid UTF-8
+        // in the computed window.  What joy!
+
+        Utf8Unit lead = *p;
+        if (mozilla::IsAscii(lead)) {
+            if (IsSingleUnitLineTerminator(lead))
+                break;
+
+            p++;
+            continue;
+        }
+
+        PeekedCodePoint<Utf8Unit> peeked = PeekCodePoint(p, limit_);
+        if (peeked.isNone())
+            break; // encoding error
+
+        char32_t c = peeked.codePoint();
+        if (MOZ_UNLIKELY(c == unicode::LINE_SEPARATOR || c == unicode::PARA_SEPARATOR))
+            break;
+
+        MOZ_ASSERT(!IsLineTerminator(c));
+
+        uint8_t len = peeked.lengthInUnits();
+        if (HalfWindowSize() + len > WindowRadius)
+            break;
+
+        p += len;
+    }
+
+    MOZ_ASSERT(HalfWindowSize() <= WindowRadius);
+    return offset + HalfWindowSize();
+}
+
 template<typename CharT, class AnyCharsAccess>
 bool
 TokenStreamSpecific<CharT, AnyCharsAccess>::advance(size_t position)
 {
     const CharT* end = this->sourceUnits.codeUnitPtrAt(position);
     while (this->sourceUnits.addressOfNextCodeUnit() < end) {
         int32_t c;
         if (!getCodePoint(&c))
@@ -871,33 +1288,20 @@ template<typename CharT, class AnyCharsA
 void
 TokenStreamSpecific<CharT, AnyCharsAccess>::currentLineAndColumn(uint32_t* line, uint32_t* column) const
 {
     const TokenStreamAnyChars& anyChars = anyCharsAccess();
     uint32_t offset = anyChars.currentToken().pos.begin;
     anyChars.srcCoords.lineNumAndColumnIndex(offset, line, column);
 }
 
-template<>
+template<typename CharT>
 bool
-TokenStreamCharsBase<Utf8Unit>::addLineOfContext(ErrorMetadata* err, uint32_t offset)
+TokenStreamCharsBase<CharT>::addLineOfContext(ErrorMetadata* err, uint32_t offset)
 {
-    // The specialization below is 100% usable if tweaked to be a definition
-    // for any CharT, but it demands SourceUnits::findWindow{Start,End} and
-    // TokenStreamCharsBase::fillCharBufferFromSourceNormalizingAsciiLineBreaks
-    // for UTF-8 that haven't been defined yet.  Use a placeholder definition
-    // til those are place.
-    return true;
-}
-
-template<>
-bool
-TokenStreamCharsBase<char16_t>::addLineOfContext(ErrorMetadata* err, uint32_t offset)
-{
-    using CharT = char16_t;
     size_t windowStart = sourceUnits.findWindowStart(offset);
     size_t windowEnd = sourceUnits.findWindowEnd(offset);
 
     size_t windowLength = windowEnd - windowStart;
     MOZ_ASSERT(windowLength <= SourceUnits::WindowRadius * 2);
 
     // Don't add a useless "line" of context when the window ends up empty
     // because of an invalid encoding at the start of a line.
@@ -1266,26 +1670,28 @@ TokenStreamSpecific<CharT, AnyCharsAcces
             }
 
             if (!this->charBuffer.append(unit))
                 return false;
 
             continue;
         }
 
-        int32_t codePoint;
-        if (!getCodePoint(&codePoint))
-            return false;
-
-        if (unicode::IsSpaceOrBOM2(codePoint)) {
-            ungetNonAsciiNormalizedCodePoint(codePoint);
+        // This ignores encoding errors: subsequent caller-side code to
+        // handle the remaining source text in the comment will do so.
+        PeekedCodePoint<CharT> peeked = this->sourceUnits.peekCodePoint();
+        if (peeked.isNone() || unicode::IsSpaceOrBOM2(peeked.codePoint()))
             break;
-        }
-
-        if (!appendCodePointToCharBuffer(codePoint))
+
+        MOZ_ASSERT(!IsLineTerminator(peeked.codePoint()),
+                   "!IsSpaceOrBOM2 must imply !IsLineTerminator or else we'll "
+                   "fail to maintain line-info/flags for EOL");
+        this->sourceUnits.consumeKnownCodePoint(peeked);
+
+        if (!appendCodePointToCharBuffer(peeked.codePoint()))
             return false;
     } while (true);
 
     if (this->charBuffer.empty()) {
         // The directive's URL was missing, but comments can contain anything,
         // so it isn't an error.
         return true;
     }
@@ -1450,41 +1856,46 @@ TokenStreamSpecific<CharT, AnyCharsAcces
         this->badToken();
     });
 
     // We've already consumed an initial code point in the identifer, to *know*
     // that this is an identifier.  So no need to worry about not consuming any
     // code points in the loop below.
     int32_t unit;
     while (true) {
-        unit = getCodeUnit();
+        unit = peekCodeUnit();
         if (unit == EOF)
             break;
 
         if (MOZ_LIKELY(isAsciiCodePoint(unit))) {
+            consumeKnownCodeUnit(unit);
+
             if (MOZ_UNLIKELY(!unicode::IsIdentifierPart(static_cast<char16_t>(unit)))) {
                 // Handle a Unicode escape -- otherwise it's not part of the
                 // identifier.
                 uint32_t codePoint;
                 if (unit != '\\' || !matchUnicodeEscapeIdent(&codePoint)) {
                     ungetCodeUnit(unit);
                     break;
                 }
 
                 escaping = IdentifierEscapes::SawUnicodeEscape;
             }
         } else {
-            int32_t codePoint;
-            if (!getNonAsciiCodePoint(unit, &codePoint))
-                return false;
-
-            if (!unicode::IsIdentifierPart(uint32_t(codePoint))) {
-                ungetNonAsciiNormalizedCodePoint(codePoint);
+            // This ignores encoding errors: subsequent caller-side code to
+            // handle source text after the IdentifierName will do so.
+            PeekedCodePoint<CharT> peeked = this->sourceUnits.peekCodePoint();
+            if (peeked.isNone() || !unicode::IsIdentifierPart(peeked.codePoint()))
                 break;
-            }
+
+            MOZ_ASSERT(!IsLineTerminator(peeked.codePoint()),
+                       "IdentifierPart must guarantee !IsLineTerminator or "
+                       "else we'll fail to maintain line-info/flags for EOL");
+
+            this->sourceUnits.consumeKnownCodePoint(peeked);
         }
     }
 
     JSAtom* atom;
     if (MOZ_UNLIKELY(escaping == IdentifierEscapes::SawUnicodeEscape)) {
         // Identifiers containing Unicode escapes have to be converted into
         // tokenbuf before atomizing.
         if (!putIdentInCharBuffer(identStart))
@@ -1498,17 +1909,17 @@ TokenStreamSpecific<CharT, AnyCharsAcces
 
         // Represent reserved words lacking escapes as reserved word tokens.
         if (const ReservedWordInfo* rw = FindReservedWord(chars, length)) {
             noteBadToken.release();
             newSimpleToken(rw->tokentype, start, modifier, out);
             return true;
         }
 
-        atom = atomizeSourceChars(anyCharsAccess().cx, chars, length);
+        atom = atomizeSourceChars(anyCharsAccess().cx, MakeSpan(chars, length));
     }
     if (!atom)
         return false;
 
     noteBadToken.release();
     newNameToken(atom->asPropertyName(), start, modifier, out);
     return true;
 }
@@ -1591,25 +2002,52 @@ static const uint8_t firstCharKinds[] = 
 #undef T_RB
 #undef T_LC
 #undef T_RC
 #undef _______
 
 static_assert(LastCharKind < (1 << (sizeof(firstCharKinds[0]) * 8)),
               "Elements of firstCharKinds[] are too small");
 
+template<>
 void
-SpecializedTokenStreamCharsBase<char16_t>::infallibleConsumeRestOfSingleLineComment()
+SourceUnits<char16_t>::consumeRestOfSingleLineComment()
 {
-    while (MOZ_LIKELY(!this->sourceUnits.atEnd())) {
-        char16_t unit = this->sourceUnits.peekCodeUnit();
+    while (MOZ_LIKELY(!atEnd())) {
+        char16_t unit = peekCodeUnit();
         if (IsLineTerminator(unit))
             return;
 
-        this->sourceUnits.consumeKnownCodeUnit(unit);
+        consumeKnownCodeUnit(unit);
+    }
+}
+
+template<>
+void
+SourceUnits<Utf8Unit>::consumeRestOfSingleLineComment()
+{
+    while (MOZ_LIKELY(!atEnd())) {
+        const Utf8Unit unit = peekCodeUnit();
+        if (IsSingleUnitLineTerminator(unit))
+            return;
+
+        if (MOZ_LIKELY(IsAscii(unit))) {
+            consumeKnownCodeUnit(unit);
+            continue;
+        }
+
+        PeekedCodePoint<Utf8Unit> peeked = peekCodePoint();
+        if (peeked.isNone())
+            return;
+
+        char32_t c = peeked.codePoint();
+        if (MOZ_UNLIKELY(c == unicode::LINE_SEPARATOR || c == unicode::PARA_SEPARATOR))
+            return;
+
+        consumeKnownCodePoint(peeked);
     }
 }
 
 template<typename CharT, class AnyCharsAccess>
 MOZ_MUST_USE bool
 TokenStreamSpecific<CharT, AnyCharsAccess>::decimalNumber(int32_t unit, TokenStart start,
                                                           const CharT* numStart,
                                                           Modifier modifier, TokenKind* out)
@@ -1681,23 +2119,20 @@ TokenStreamSpecific<CharT, AnyCharsAcces
     // two tokens, necessitating this unaesthetic lookahead.)
     if (unit != EOF) {
         if (MOZ_LIKELY(isAsciiCodePoint(unit))) {
             if (unicode::IsIdentifierStart(char16_t(unit))) {
                 error(JSMSG_IDSTART_AFTER_NUMBER);
                 return false;
             }
         } else {
-            int32_t codePoint;
-            if (!getCodePoint(&codePoint))
-                return false;
-
-            ungetNonAsciiNormalizedCodePoint(codePoint);
-
-            if (unicode::IsIdentifierStart(uint32_t(codePoint))) {
+            // This ignores encoding errors: subsequent caller-side code to
+            // handle source text after the number will do so.
+            PeekedCodePoint<CharT> peeked = this->sourceUnits.peekCodePoint();
+            if (!peeked.isNone() && unicode::IsIdentifierStart(peeked.codePoint())) {
                 error(JSMSG_IDSTART_AFTER_NUMBER);
                 return false;
             }
         }
     }
 
     noteBadToken.release();
     newNumberToken(dval, decimalPoint, start, modifier, out);
@@ -1838,63 +2273,80 @@ TokenStreamSpecific<CharT, AnyCharsAcces
     // Check if in the middle of a template string. Have to get this out of
     // the way first.
     if (MOZ_UNLIKELY(modifier == TemplateTail))
         return getStringOrTemplateToken('`', modifier, ttp);
 
     // This loop runs more than once only when whitespace or comments are
     // encountered.
     do {
-        int32_t unit = getCodeUnit();
+        int32_t unit = peekCodeUnit();
         if (MOZ_UNLIKELY(unit == EOF)) {
             MOZ_ASSERT(this->sourceUnits.atEnd());
             anyCharsAccess().flags.isEOF = true;
             TokenStart start(this->sourceUnits, 0);
             newSimpleToken(TokenKind::Eof, start, modifier, ttp);
             return true;
         }
 
         if (MOZ_UNLIKELY(!isAsciiCodePoint(unit))) {
             // Non-ASCII code points can only be identifiers or whitespace.
             // It would be nice to compute these *after* discarding whitespace,
             // but IN A WORLD where |unicode::IsSpaceOrBOM2| requires consuming
             // a variable number of code points, it's easier to assume it's an
             // identifier and maybe do a little wasted work, than to unget and
             // compute and reget if whitespace.
-            TokenStart start(this->sourceUnits, -1);
-            const CharT* identStart = this->sourceUnits.addressOfNextCodeUnit() - 1;
-
-            int32_t codePoint;
-            if (!getNonAsciiCodePoint(unit, &codePoint))
+            TokenStart start(this->sourceUnits, 0);
+            const CharT* identStart = this->sourceUnits.addressOfNextCodeUnit();
+
+            PeekedCodePoint<CharT> peeked = this->sourceUnits.peekCodePoint();
+            if (peeked.isNone()) {
+                int32_t bad;
+                MOZ_ALWAYS_FALSE(getCodePoint(&bad));
                 return badToken();
-
-            if (unicode::IsSpaceOrBOM2(codePoint)) {
-                if (codePoint == '\n')
+            }
+
+            char32_t cp = peeked.codePoint();
+            if (unicode::IsSpaceOrBOM2(cp)) {
+                this->sourceUnits.consumeKnownCodePoint(peeked);
+                if (IsLineTerminator(cp)) {
+                    if (!updateLineInfoForEOL())
+                        return badToken();
+
                     anyCharsAccess().updateFlagsForEOL();
+                }
 
                 continue;
             }
 
             static_assert(isAsciiCodePoint('$'),
                           "IdentifierStart contains '$', but as "
                           "!IsUnicodeIDStart('$'), ensure that '$' is never "
                           "handled here");
             static_assert(isAsciiCodePoint('_'),
                           "IdentifierStart contains '_', but as "
                           "!IsUnicodeIDStart('_'), ensure that '_' is never "
                           "handled here");
 
-            if (unicode::IsUnicodeIDStart(uint32_t(codePoint)))
+            if (MOZ_LIKELY(unicode::IsUnicodeIDStart(cp))) {
+                this->sourceUnits.consumeKnownCodePoint(peeked);
+                MOZ_ASSERT(!IsLineTerminator(cp),
+                           "IdentifierStart must guarantee !IsLineTerminator "
+                           "or else we'll fail to maintain line-info/flags "
+                           "for EOL here");
+
                 return identifierName(start, identStart, IdentifierEscapes::None, modifier, ttp);
-
-            ungetCodePointIgnoreEOL(codePoint);
+            }
+
             error(JSMSG_ILLEGAL_CHARACTER);
             return badToken();
         } // !isAsciiCodePoint(unit)
 
+        consumeKnownCodeUnit(unit);
+
         // Get the token kind, based on the first char.  The ordering of c1kind
         // comparison is based on the frequency of tokens in real code:
         // Parsemark (which represents typical JS code on the web) and the
         // Unreal demo (which represents asm.js code).
         //
         //                  Parsemark   Unreal
         //  OneChar         32.9%       39.7%
         //  Space           25.0%        0.6%
@@ -2042,39 +2494,31 @@ TokenStreamSpecific<CharT, AnyCharsAcces
                 // '0' not followed by [XxBbOo0-9];  scan as a decimal number.
                 numStart = this->sourceUnits.addressOfNextCodeUnit() - 1;
 
                 // NOTE: |unit| may be EOF here.  (This is permitted by case #3
                 //       in TokenStream.h docs for this function.)
                 return decimalNumber(unit, start, numStart, modifier, ttp);
             }
 
-            // Check for an identifier-start code point immediately after the
-            // number.  This must be an error, and somewhat surprisingly, if
-            // a check doesn't happen here, it never will.
-            if (MOZ_UNLIKELY(unit == EOF)) {
-                // Technically this isn't necessary -- ungetting EOF does
-                // nothing -- but it's conceptually nicer if we consider all
-                // gets requiring an unget to revert them.
-                ungetCodeUnit(unit);
-            } else if (MOZ_LIKELY(isAsciiCodePoint(unit))) {
-                ungetCodeUnit(unit);
-
+            ungetCodeUnit(unit);
+
+            // Error if an identifier-start code point appears immediately
+            // after the number.  Somewhat surprisingly, if we don't check
+            // here, we'll never check at all.
+            if (MOZ_LIKELY(isAsciiCodePoint(unit))) {
                 if (unicode::IsIdentifierStart(char16_t(unit))) {
                     error(JSMSG_IDSTART_AFTER_NUMBER);
                     return badToken();
                 }
-            } else {
-                int32_t codePoint;
-                if (!getNonAsciiCodePoint(unit, &codePoint))
-                    return badToken();
-
-                ungetNonAsciiNormalizedCodePoint(codePoint);
-
-                if (unicode::IsIdentifierStart(uint32_t(codePoint))) {
+            } else if (MOZ_LIKELY(unit != EOF)) {
+                // This ignores encoding errors: subsequent caller-side code to
+                // handle source text after the number will do so.
+                PeekedCodePoint<CharT> peeked = this->sourceUnits.peekCodePoint();
+                if (!peeked.isNone() && unicode::IsIdentifierStart(peeked.codePoint())) {
                     error(JSMSG_IDSTART_AFTER_NUMBER);
                     return badToken();
                 }
             }
 
             double dval;
             const char16_t* dummy;
             if (!GetPrefixInteger(anyCharsAccess().cx, numStart,
@@ -2184,19 +2628,17 @@ TokenStreamSpecific<CharT, AnyCharsAcces
             break;
 
           case '<':
             if (anyCharsAccess().options().allowHTMLComments) {
                 // Treat HTML begin-comment as comment-till-end-of-line.
                 if (matchCodeUnit('!')) {
                     if (matchCodeUnit('-')) {
                         if (matchCodeUnit('-')) {
-                            if (!consumeRestOfSingleLineComment())
-                                return false;
-
+                            this->sourceUnits.consumeRestOfSingleLineComment();
                             continue;
                         }
                         ungetCodeUnit('-');
                     }
                     ungetCodeUnit('!');
                 }
             }
             if (matchCodeUnit('<'))
@@ -2231,19 +2673,17 @@ TokenStreamSpecific<CharT, AnyCharsAcces
                     bool shouldWarn = unit == '@';
                     if (!getDirectives(false, shouldWarn))
                         return false;
                 } else {
                     // NOTE: |unit| may be EOF here.
                     ungetCodeUnit(unit);
                 }
 
-                if (!consumeRestOfSingleLineComment())
-                    return false;
-
+                this->sourceUnits.consumeRestOfSingleLineComment();
                 continue;
             }
 
             // Look for a multi-line comment.
             if (matchCodeUnit('*')) {
                 TokenStreamAnyChars& anyChars = anyCharsAccess();
                 unsigned linenoBefore = anyChars.lineno;
 
@@ -2290,19 +2730,17 @@ TokenStreamSpecific<CharT, AnyCharsAcces
             break;
 
           case '-':
             if (matchCodeUnit('-')) {
                 if (anyCharsAccess().options().allowHTMLComments &&
                     !anyCharsAccess().flags.isDirtyLine)
                 {
                     if (matchCodeUnit('>')) {
-                        if (!consumeRestOfSingleLineComment())
-                            return false;
-
+                        this->sourceUnits.consumeRestOfSingleLineComment();
                         continue;
                     }
                 }
 
                 simpleKind = TokenKind::Dec;
             } else {
                 simpleKind = matchCodeUnit('=') ? TokenKind::SubAssign : TokenKind::Sub;
             }
@@ -2711,16 +3149,20 @@ TokenKindToString(TokenKind tt)
 
 template class TokenStreamCharsBase<Utf8Unit>;
 template class TokenStreamCharsBase<char16_t>;
 
 template class TokenStreamChars<char16_t, TokenStreamAnyCharsAccess>;
 template class TokenStreamSpecific<char16_t, TokenStreamAnyCharsAccess>;
 
 template class
+TokenStreamChars<Utf8Unit, ParserAnyCharsAccess<GeneralParser<FullParseHandler, Utf8Unit>>>;
+template class
+TokenStreamChars<Utf8Unit, ParserAnyCharsAccess<GeneralParser<SyntaxParseHandler, Utf8Unit>>>;
+template class
 TokenStreamChars<char16_t, ParserAnyCharsAccess<GeneralParser<FullParseHandler, char16_t>>>;
 template class
 TokenStreamChars<char16_t, ParserAnyCharsAccess<GeneralParser<SyntaxParseHandler, char16_t>>>;
 
 template class
 TokenStreamSpecific<char16_t, ParserAnyCharsAccess<GeneralParser<FullParseHandler, char16_t>>>;
 template class
 TokenStreamSpecific<char16_t, ParserAnyCharsAccess<GeneralParser<SyntaxParseHandler, char16_t>>>;
--- a/js/src/frontend/TokenStream.h
+++ b/js/src/frontend/TokenStream.h
@@ -180,26 +180,29 @@
  * TokenStreamSpecific declarer to specify this is more explicit), we couldn't.
  */
 
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/Casting.h"
 #include "mozilla/DebugOnly.h"
+#include "mozilla/Maybe.h"
 #include "mozilla/MemoryChecking.h"
 #include "mozilla/PodOperations.h"
+#include "mozilla/Span.h"
 #include "mozilla/TextUtils.h"
 #include "mozilla/TypeTraits.h"
 #include "mozilla/Unused.h"
 #include "mozilla/Utf8.h"
 
 #include <algorithm>
 #include <stdarg.h>
 #include <stddef.h>
+#include <stdint.h>
 #include <stdio.h>
 
 #include "jspubtd.h"
 
 #include "frontend/ErrorReporter.h"
 #include "frontend/TokenKind.h"
 #include "js/UniquePtr.h"
 #include "js/Vector.h"
@@ -964,16 +967,166 @@ IsLineTerminator(char32_t codePoint)
 
 inline bool
 IsLineTerminator(char16_t unit)
 {
     // Every LineTerminator fits in char16_t, so this is exact.
     return IsLineTerminator(static_cast<char32_t>(unit));
 }
 
+template<typename CharT>
+struct SourceUnitTraits;
+
+template<>
+struct SourceUnitTraits<char16_t>
+{
+  public:
+    static constexpr uint8_t maxUnitsLength = 2;
+
+    static constexpr size_t lengthInUnits(char32_t codePoint) {
+        return codePoint < unicode::NonBMPMin ? 1 : 2;
+    }
+};
+
+template<>
+struct SourceUnitTraits<mozilla::Utf8Unit>
+{
+  public:
+    static constexpr uint8_t maxUnitsLength = 4;
+
+    static constexpr size_t lengthInUnits(char32_t codePoint) {
+        return codePoint < 0x80
+               ? 1
+               : codePoint < 0x800
+               ? 2
+               : codePoint < 0x10000
+               ? 3
+               : 4;
+    }
+