Merge m-c to fx-team. a=merge
authorRyan VanderMeulen <ryanvm@gmail.com>
Tue, 17 Feb 2015 21:24:49 -0500
changeset 229564 6500f3e51d7860e955811f28232b95d2eeb9eb12
parent 229482 15edc0cdbae7f203c0919736922ddd9c6746520f (current diff)
parent 229563 93ddd99ffd86b5fd925a02b6d83a6e69c57e32b6 (diff)
child 229565 840ddbf2de5ee4db39d639df422553f4803f415b
push id11358
push userryanvm@gmail.com
push dateWed, 18 Feb 2015 02:25:06 +0000
treeherderfx-team@6500f3e51d78 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone38.0a1
Merge m-c to fx-team. a=merge
js/src/tests/ecma_7/SIMD/float32x4with.js
js/src/tests/ecma_7/SIMD/float64x2with.js
js/src/tests/ecma_7/SIMD/int32x4with.js
toolkit/mozapps/extensions/content/openH264Prefs.xul
toolkit/mozapps/extensions/internal/OpenH264Provider.jsm
toolkit/mozapps/extensions/test/browser/browser_openH264.js
toolkit/mozapps/extensions/test/xpcshell/test_openh264.js
--- a/accessible/ipc/DocAccessibleChild.cpp
+++ b/accessible/ipc/DocAccessibleChild.cpp
@@ -220,17 +220,17 @@ DocAccessibleChild::RecvTextSubstring(co
 
   acc->TextSubstring(aStartOffset, aEndOffset, *aText);
   return true;
 }
 
 bool
 DocAccessibleChild::RecvGetTextAfterOffset(const uint64_t& aID,
                                            const int32_t& aOffset,
-                                           const AccessibleTextBoundary& aBoundaryType,
+                                           const int32_t& aBoundaryType,
                                            nsString* aText,
                                            int32_t* aStartOffset,
                                            int32_t* aEndOffset)
 {
   *aStartOffset = 0;
   *aEndOffset = 0;
   HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
   if (acc) {
@@ -238,17 +238,17 @@ DocAccessibleChild::RecvGetTextAfterOffs
                          aStartOffset, aEndOffset, *aText);
   }
   return true;
 }
 
 bool
 DocAccessibleChild::RecvGetTextAtOffset(const uint64_t& aID,
                                         const int32_t& aOffset,
-                                        const AccessibleTextBoundary& aBoundaryType,
+                                        const int32_t& aBoundaryType,
                                         nsString* aText,
                                         int32_t* aStartOffset,
                                         int32_t* aEndOffset)
 {
   *aStartOffset = 0;
   *aEndOffset = 0;
   HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
   if (acc) {
@@ -256,17 +256,17 @@ DocAccessibleChild::RecvGetTextAtOffset(
                       aStartOffset, aEndOffset, *aText);
   }
   return true;
 }
 
 bool
 DocAccessibleChild::RecvGetTextBeforeOffset(const uint64_t& aID,
                                             const int32_t& aOffset,
-                                            const AccessibleTextBoundary& aBoundaryType,
+                                            const int32_t& aBoundaryType,
                                             nsString* aText,
                                             int32_t* aStartOffset,
                                             int32_t* aEndOffset)
 {
   *aStartOffset = 0;
   *aEndOffset = 0;
   HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
   if (acc) {
--- a/accessible/ipc/DocAccessibleChild.h
+++ b/accessible/ipc/DocAccessibleChild.h
@@ -65,27 +65,27 @@ public:
                               nsTArray<Attribute> *aAttributes) MOZ_OVERRIDE;
   virtual bool RecvTextSubstring(const uint64_t& aID,
                                  const int32_t& aStartOffset,
                                  const int32_t& aEndOffset, nsString* aText)
     MOZ_OVERRIDE;
 
   virtual bool RecvGetTextAfterOffset(const uint64_t& aID,
                                       const int32_t& aOffset,
-                                      const AccessibleTextBoundary& aBoundaryType,
+                                      const int32_t& aBoundaryType,
                                       nsString* aText, int32_t* aStartOffset,
                                       int32_t* aEndOffset) MOZ_OVERRIDE;
   virtual bool RecvGetTextAtOffset(const uint64_t& aID,
                                    const int32_t& aOffset,
-                                   const AccessibleTextBoundary& aBoundaryType,
+                                   const int32_t& aBoundaryType,
                                    nsString* aText, int32_t* aStartOffset,
                                    int32_t* aEndOffset) MOZ_OVERRIDE;
   virtual bool RecvGetTextBeforeOffset(const uint64_t& aID,
                                        const int32_t& aOffset,
-                                       const AccessibleTextBoundary& aBoundaryType,
+                                       const int32_t& aBoundaryType,
                                        nsString* aText, int32_t* aStartOffset,
                                        int32_t* aEndOffset) MOZ_OVERRIDE;
 
 private:
   DocAccessible* mDoc;
 };
 
 }
--- a/accessible/ipc/PDocAccessible.ipdl
+++ b/accessible/ipc/PDocAccessible.ipdl
@@ -1,18 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 include protocol PContent;
 
-using AccessibleTextBoundary from "nsIAccessibleText.h";
-
 namespace mozilla {
 namespace a11y {
 
 struct AccessibleData
 {
   uint64_t ID;
   uint32_t Role;
   uint32_t ChildrenCount;
@@ -64,18 +62,18 @@ child:
     returns(uint64_t[] targets);
   prio(high) sync Relations(uint64_t aID) returns(RelationTargets[] relations);
 
   // AccessibleText
 
   // TextSubstring is getText in IDL.
   prio(high) sync TextSubstring(uint64_t aID, int32_t aStartOffset, int32_t
                                 aEndOffset) returns(nsString aText);
-  prio(high) sync GetTextAfterOffset(uint64_t aID, int32_t aOffset, AccessibleTextBoundary aBoundaryType)
+  prio(high) sync GetTextAfterOffset(uint64_t aID, int32_t aOffset, int32_t aBoundaryType)
     returns(nsString aText, int32_t aStartOffset, int32_t aEndOffset);
-  prio(high) sync GetTextAtOffset(uint64_t aID, int32_t aOffset, AccessibleTextBoundary aBoundaryType)
+  prio(high) sync GetTextAtOffset(uint64_t aID, int32_t aOffset, int32_t aBoundaryType)
     returns(nsString aText, int32_t aStartOffset, int32_t aEndOffset);
-  prio(high) sync GetTextBeforeOffset(uint64_t aID, int32_t aOffset, AccessibleTextBoundary aBoundaryType)
+  prio(high) sync GetTextBeforeOffset(uint64_t aID, int32_t aOffset, int32_t aBoundaryType)
     returns(nsString aText, int32_t aStartOffset, int32_t aEndOffset);
 };
 
 }
 }
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -683,16 +683,19 @@ pref("javascript.options.mem.gc_min_empt
 pref("javascript.options.mem.gc_max_empty_chunk_count", 2);
 
 // Show/Hide scrollbars when active/inactive
 pref("ui.showHideScrollbars", 1);
 pref("ui.useOverlayScrollbars", 1);
 pref("ui.scrollbarFadeBeginDelay", 450);
 pref("ui.scrollbarFadeDuration", 200);
 
+// Scrollbar position follows the document `dir` attribute
+pref("layout.scrollbar.side", 1);
+
 // Enable the ProcessPriorityManager, and give processes with no visible
 // documents a 1s grace period before they're eligible to be marked as
 // background. Background processes that are perceivable due to playing
 // media are given a longer grace period to accomodate changing tracks, etc.
 pref("dom.ipc.processPriorityManager.enabled", true);
 pref("dom.ipc.processPriorityManager.backgroundGracePeriodMS", 1000);
 pref("dom.ipc.processPriorityManager.backgroundPerceivableGracePeriodMS", 5000);
 pref("dom.ipc.processPriorityManager.temporaryPriorityLockMS", 5000);
@@ -1109,15 +1112,13 @@ pref("dom.requestSync.enabled", true);
 
 // Only enable for kit kat and above devices
 // kit kat == 19, L = 21, 20 is kit-kat for wearables
 // 15 is for the ICS emulators which will fallback to software vsync
 #if ANDROID_VERSION == 19 || ANDROID_VERSION == 21 || ANDROID_VERSION == 15
 pref("gfx.vsync.hw-vsync.enabled", true);
 pref("gfx.vsync.compositor", true);
 pref("gfx.touch.resample", true);
-pref("gfx.vsync.refreshdriver", true);
 #else
 pref("gfx.vsync.hw-vsync.enabled", false);
 pref("gfx.vsync.compositor", false);
 pref("gfx.touch.resample", false);
-pref("gfx.vsync.refreshdriver", false);
 #endif
--- a/b2g/chrome/content/content.css
+++ b/b2g/chrome/content/content.css
@@ -31,16 +31,23 @@ html xul|scrollbar {
 }
 
 xul|scrollbar[orient="vertical"] {
   -moz-margin-start: -8px;
   min-width: 8px;
   max-width: 8px;
 }
 
+/* workaround for bug 1119057: as -moz-margin-start may not work as expected,
+ * force a right margin value in RTL mode.  */
+[dir="rtl"] xul|scrollbar[root="true"][orient="vertical"] {
+  -moz-margin-start: unset;
+  margin-right: -8px;
+}
+
 xul|scrollbar[orient="vertical"] xul|thumb {
   max-width: 6px !important;
   min-width: 6px !important;
 }
 
 xul|scrollbar[orient="horizontal"] {
   margin-top: -8px;
   min-height: 8px;
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -10,21 +10,21 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="cdaa0a4ac28c781709df8c318ed079e9e475503a">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="4f39e48b95fa00c8669b8707447542024bb55432"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="82f286f10a41aab84a0796c89fbefe67b179994b"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
-  <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
+  <project name="moztt" path="external/moztt" remote="b2g" revision="c42985975f2bbc42859b9136ed348186d989b93d"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d0d11d190ccc50d7d66009bcc896ad4b42d3f0d"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="8b880805d454664b3eed11d0f053cdeafa1ff06e"/>
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -14,22 +14,22 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="6295c4eb38de793159368aa7f745ef3faf7208aa">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="4f39e48b95fa00c8669b8707447542024bb55432"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="82f286f10a41aab84a0796c89fbefe67b179994b"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="eb1795a9002eb142ac58c8d68f8f4ba094af07ca"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="2c31ac3a31a340b40ecd9c291df9b9613d3afa72"/>
-  <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
+  <project name="moztt" path="external/moztt" remote="b2g" revision="c42985975f2bbc42859b9136ed348186d989b93d"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d0d11d190ccc50d7d66009bcc896ad4b42d3f0d"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
   <project name="platform_bionic" path="bionic" remote="b2g" revision="e2b3733ba3fa5e3f404e983d2e4142b1f6b1b846"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="425f8b5fadf5889834c5acd27d23c9e0b2129c28"/>
   <project name="device/common" path="device/common" revision="42b808b7e93d0619286ae8e59110b176b7732389"/>
   <project name="device/sample" path="device/sample" revision="237bd668d0f114d801a8d6455ef5e02cc3577587"/>
   <project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="11816ad0406744f963537b23d68ed9c2afb412bd"/>
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -12,19 +12,19 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="ac778ae59be38aea284a04c89640b1a11c26a5de">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="4f39e48b95fa00c8669b8707447542024bb55432"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="82f286f10a41aab84a0796c89fbefe67b179994b"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
-  <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
+  <project name="moztt" path="external/moztt" remote="b2g" revision="c42985975f2bbc42859b9136ed348186d989b93d"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d0d11d190ccc50d7d66009bcc896ad4b42d3f0d"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="9025e50b9d29b3cabbbb21e1dd94d0d13121a17e"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="b89fda71fcd0fa0cf969310e75be3ea33e048b44"/>
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -10,21 +10,21 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="cdaa0a4ac28c781709df8c318ed079e9e475503a">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="4f39e48b95fa00c8669b8707447542024bb55432"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="82f286f10a41aab84a0796c89fbefe67b179994b"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
-  <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
+  <project name="moztt" path="external/moztt" remote="b2g" revision="c42985975f2bbc42859b9136ed348186d989b93d"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d0d11d190ccc50d7d66009bcc896ad4b42d3f0d"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="f92a936f2aa97526d4593386754bdbf02db07a12"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="6e47ff2790f5656b5b074407829ceecf3e6188c4"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="1950e4760fa14688b83cdbb5acaa1af9f82ef434"/>
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -14,22 +14,22 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="6295c4eb38de793159368aa7f745ef3faf7208aa">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="4f39e48b95fa00c8669b8707447542024bb55432"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="82f286f10a41aab84a0796c89fbefe67b179994b"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="eb1795a9002eb142ac58c8d68f8f4ba094af07ca"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="2c31ac3a31a340b40ecd9c291df9b9613d3afa72"/>
-  <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
+  <project name="moztt" path="external/moztt" remote="b2g" revision="c42985975f2bbc42859b9136ed348186d989b93d"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d0d11d190ccc50d7d66009bcc896ad4b42d3f0d"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
   <project name="platform_bionic" path="bionic" remote="b2g" revision="e2b3733ba3fa5e3f404e983d2e4142b1f6b1b846"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="425f8b5fadf5889834c5acd27d23c9e0b2129c28"/>
   <project name="device/common" path="device/common" revision="42b808b7e93d0619286ae8e59110b176b7732389"/>
   <project name="device/sample" path="device/sample" revision="237bd668d0f114d801a8d6455ef5e02cc3577587"/>
   <project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="11816ad0406744f963537b23d68ed9c2afb412bd"/>
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -10,21 +10,21 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="cdaa0a4ac28c781709df8c318ed079e9e475503a">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="4f39e48b95fa00c8669b8707447542024bb55432"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="82f286f10a41aab84a0796c89fbefe67b179994b"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
-  <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
+  <project name="moztt" path="external/moztt" remote="b2g" revision="c42985975f2bbc42859b9136ed348186d989b93d"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d0d11d190ccc50d7d66009bcc896ad4b42d3f0d"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="8b880805d454664b3eed11d0f053cdeafa1ff06e"/>
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -12,19 +12,19 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="ac778ae59be38aea284a04c89640b1a11c26a5de">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="4f39e48b95fa00c8669b8707447542024bb55432"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="82f286f10a41aab84a0796c89fbefe67b179994b"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
-  <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
+  <project name="moztt" path="external/moztt" remote="b2g" revision="c42985975f2bbc42859b9136ed348186d989b93d"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d0d11d190ccc50d7d66009bcc896ad4b42d3f0d"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="e95b4ce22c825da44d14299e1190ea39a5260bde"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="471afab478649078ad7c75ec6b252481a59e19b8"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
 {
     "git": {
-        "git_revision": "4f39e48b95fa00c8669b8707447542024bb55432", 
+        "git_revision": "82f286f10a41aab84a0796c89fbefe67b179994b", 
         "remote": "https://git.mozilla.org/releases/gaia.git", 
         "branch": ""
     }, 
-    "revision": "e0816d2581cdc2d0581f625c06811128c87c0c48", 
+    "revision": "066f0e84321a010700467d1814ee0048dca7e5e1", 
     "repo_path": "integration/gaia-central"
 }
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -12,19 +12,19 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="ac778ae59be38aea284a04c89640b1a11c26a5de">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="4f39e48b95fa00c8669b8707447542024bb55432"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="82f286f10a41aab84a0796c89fbefe67b179994b"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
-  <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
+  <project name="moztt" path="external/moztt" remote="b2g" revision="c42985975f2bbc42859b9136ed348186d989b93d"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d0d11d190ccc50d7d66009bcc896ad4b42d3f0d"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="9025e50b9d29b3cabbbb21e1dd94d0d13121a17e"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="b89fda71fcd0fa0cf969310e75be3ea33e048b44"/>
--- a/b2g/config/nexus-5-l/sources.xml
+++ b/b2g/config/nexus-5-l/sources.xml
@@ -10,21 +10,21 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="7f2ee9f4cb926684883fc2a2e407045fd9db2199">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="4f39e48b95fa00c8669b8707447542024bb55432"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="82f286f10a41aab84a0796c89fbefe67b179994b"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
-  <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
+  <project name="moztt" path="external/moztt" remote="b2g" revision="c42985975f2bbc42859b9136ed348186d989b93d"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d0d11d190ccc50d7d66009bcc896ad4b42d3f0d"/>
   <!-- Stock Android things -->
   <project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="50d1ca4ab8add54523b7bc692860d57e8ee4c0d1"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="fb3845864573857677f9b500040a8f011eaf5078"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" revision="354496e8eddd28c743d8e02c02eeab02958367e6"/>
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1804,18 +1804,18 @@ pref("browser.translation.ui.show", fals
 
 // Telemetry experiments settings.
 pref("experiments.enabled", true);
 pref("experiments.manifest.fetchIntervalSeconds", 86400);
 pref("experiments.manifest.uri", "https://telemetry-experiment.cdn.mozilla.net/manifest/v1/firefox/%VERSION%/%CHANNEL%");
 // Whether experiments are supported by the current application profile.
 pref("experiments.supported", true);
 
-// Enable the OpenH264 plugin support in the addon manager.
-pref("media.gmp-gmpopenh264.provider.enabled", true);
+// Enable GMP support in the addon manager.
+pref("media.gmp-provider.enabled", true);
 
 pref("browser.apps.URL", "https://marketplace.firefox.com/discovery/");
 
 #ifdef NIGHTLY_BUILD
 pref("browser.polaris.enabled", false);
 pref("privacy.trackingprotection.ui.enabled", false);
 #endif
 
--- a/browser/components/loop/LoopCalls.jsm
+++ b/browser/components/loop/LoopCalls.jsm
@@ -64,19 +64,26 @@ CallProgressSocket.prototype = {
     if (Services.io.offline) {
       this._onError("IO offline");
       return;
     }
 
     let uri = Services.io.newURI(this._progressUrl, null, null);
 
     // Allow _websocket to be set for testing.
-    this._websocket = this._websocket ||
-      Cc["@mozilla.org/network/protocol;1?name=" + uri.scheme]
-        .createInstance(Ci.nsIWebSocketChannel);
+    if (!this._websocket) {
+      this._websocket = Cc["@mozilla.org/network/protocol;1?name=" + uri.scheme]
+                          .createInstance(Ci.nsIWebSocketChannel);
+
+      this._websocket.initLoadInfo(null, // aLoadingNode
+                                   Services.scriptSecurityManager.getSystemPrincipal(),
+                                   null, // aTriggeringPrincipal
+                                   Ci.nsILoadInfo.SEC_NORMAL,
+                                   Ci.nsIContentPolicy.TYPE_WEBSOCKET);
+    }
 
     this._websocket.asyncOpen(uri, this._progressUrl, this, null);
   },
 
   /**
    * Listener method, handles the start of the websocket stream.
    * Sends a hello message to the server.
    *
--- a/browser/components/loop/MozLoopPushHandler.jsm
+++ b/browser/components/loop/MozLoopPushHandler.jsm
@@ -56,16 +56,21 @@ PushSocket.prototype = {
 
     this._onMsg = onMsg;
     this._onStart = onStart;
     this._onClose = onClose;
 
     if (!this._websocket) {
       this._websocket = Cc["@mozilla.org/network/protocol;1?name=wss"]
                           .createInstance(Ci.nsIWebSocketChannel);
+      this._websocket.initLoadInfo(null, // aLoadingNode
+                                   Services.scriptSecurityManager.getSystemPrincipal(),
+                                   null, // aTriggeringPrincipal
+                                   Ci.nsILoadInfo.SEC_NORMAL,
+                                   Ci.nsIContentPolicy.TYPE_WEBSOCKET);
     }
 
     let uri = Services.io.newURI(pushUri, null, null);
     this._websocket.protocol = "push-notification";
     this._websocket.asyncOpen(uri, pushUri, this, null);
   },
 
   /**
--- a/docshell/base/LoadInfo.h
+++ b/docshell/base/LoadInfo.h
@@ -15,16 +15,17 @@
 
 class nsINode;
 
 namespace mozilla {
 
 namespace net {
 class HttpChannelParent;
 class FTPChannelParent;
+class WebSocketChannelParent;
 }
 
 /**
  * Class that provides an nsILoadInfo implementation.
  */
 class MOZ_EXPORT LoadInfo MOZ_FINAL : public nsILoadInfo
 {
 public:
@@ -46,16 +47,17 @@ private:
   LoadInfo(nsIPrincipal* aLoadingPrincipal,
            nsIPrincipal* aTriggeringPrincipal,
            nsSecurityFlags aSecurityFlags,
            nsContentPolicyType aContentPolicyType,
            uint32_t aInnerWindowID);
 
   friend class net::HttpChannelParent;
   friend class net::FTPChannelParent;
+  friend class net::WebSocketChannelParent;
 
   ~LoadInfo();
 
   nsCOMPtr<nsIPrincipal> mLoadingPrincipal;
   nsCOMPtr<nsIPrincipal> mTriggeringPrincipal;
   nsWeakPtr mLoadingContext;
   nsSecurityFlags mSecurityFlags;
   nsContentPolicyType mContentPolicyType;
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -585,17 +585,26 @@ SendPing(void* aClosure, nsIContent* aCo
     if (!IsSameHost(aURI, info->referrer)) {
       return;
     }
   }
 
   nsIDocument* doc = aContent->OwnerDoc();
 
   nsCOMPtr<nsIChannel> chan;
-  aIOService->NewChannelFromURI(aURI, getter_AddRefs(chan));
+  NS_NewChannel(getter_AddRefs(chan),
+                aURI,
+                doc,
+                nsILoadInfo::SEC_NORMAL,
+                nsIContentPolicy::TYPE_PING,
+                nullptr, // aLoadGroup
+                nullptr, // aCallbacks
+                nsIRequest::LOAD_NORMAL, // aLoadFlags,
+                aIOService);
+
   if (!chan) {
     return;
   }
 
   // Don't bother caching the result of this URI load.
   chan->SetLoadFlags(nsIRequest::INHIBIT_CACHING);
 
   nsCOMPtr<nsIHttpChannel> httpChan = do_QueryInterface(chan);
--- a/dom/base/WebSocket.cpp
+++ b/dom/base/WebSocket.cpp
@@ -85,16 +85,17 @@ public:
   , mCloseEventCode(nsIWebSocketChannel::CLOSE_ABNORMAL)
   , mScriptLine(0)
   , mInnerWindowID(0)
   , mWorkerPrivate(nullptr)
 #ifdef DEBUG
   , mHasFeatureRegistered(false)
 #endif
   , mIsMainThread(true)
+  , mMutex("WebSocketImpl::mMutex")
   , mWorkerShuttingDown(false)
   {
     if (!NS_IsMainThread()) {
       mWorkerPrivate = GetCurrentThreadWorkerPrivate();
       MOZ_ASSERT(mWorkerPrivate);
       mIsMainThread = false;
     }
   }
@@ -217,16 +218,19 @@ public:
     MutexAutoLock lock(mWebSocket->mMutex);
     mHasFeatureRegistered = aValue;
   }
 #endif
 
   nsWeakPtr mWeakLoadGroup;
 
   bool mIsMainThread;
+
+  // This mutex protects mWorkerShuttingDown.
+  mozilla::Mutex mMutex;
   bool mWorkerShuttingDown;
 
 private:
   ~WebSocketImpl()
   {
     // If we threw during Init we never called disconnect
     if (!mDisconnectingOrDisconnected) {
       Disconnect();
@@ -417,17 +421,24 @@ class MOZ_STACK_CLASS MaybeDisconnect
 public:
   explicit MaybeDisconnect(WebSocketImpl* aImpl)
     : mImpl(aImpl)
   {
   }
 
   ~MaybeDisconnect()
   {
-    if (mImpl->mWorkerShuttingDown) {
+    bool toDisconnect = false;
+
+    {
+      MutexAutoLock lock(mImpl->mMutex);
+      toDisconnect = mImpl->mWorkerShuttingDown;
+    }
+
+    if (toDisconnect) {
       mImpl->Disconnect();
     }
   }
 
 private:
   WebSocketImpl* mImpl;
 };
 
@@ -881,17 +892,17 @@ WebSocketImpl::GetInterface(const nsIID&
 
 WebSocket::WebSocket(nsPIDOMWindow* aOwnerWindow)
   : DOMEventTargetHelper(aOwnerWindow)
   , mIsMainThread(true)
   , mKeepingAlive(false)
   , mCheckMustKeepAlive(true)
   , mOutgoingBufferedAmount(0)
   , mBinaryType(dom::BinaryType::Blob)
-  , mMutex("WebSocketImpl::mMutex")
+  , mMutex("WebSocket::mMutex")
   , mReadyState(CONNECTING)
 {
   mImpl = new WebSocketImpl(this);
   mIsMainThread = mImpl->mIsMainThread;
 }
 
 WebSocket::~WebSocket()
 {
@@ -1558,25 +1569,21 @@ WebSocketImpl::InitializeConnection()
   // manually adding loadinfo to the channel since it
   // was not set during channel creation.
   nsCOMPtr<nsIDocument> doc = do_QueryReferent(mOriginDocument);
 
   // mOriginDocument has to be release on main-thread because WeakReferences
   // are not thread-safe.
   mOriginDocument = nullptr;
 
-  nsCOMPtr<nsILoadInfo> loadInfo =
-    new LoadInfo(doc ?
-                   doc->NodePrincipal() : mPrincipal.get(),
-                 mPrincipal,
-                 doc,
-                 nsILoadInfo::SEC_NORMAL,
-                 nsIContentPolicy::TYPE_WEBSOCKET);
-  rv = wsChannel->SetLoadInfo(loadInfo);
-  NS_ENSURE_SUCCESS(rv, rv);
+  wsChannel->InitLoadInfo(doc ? doc->AsDOMNode() : nullptr,
+                          doc ? doc->NodePrincipal() : mPrincipal.get(),
+                          mPrincipal,
+                          nsILoadInfo::SEC_NORMAL,
+                          nsIContentPolicy::TYPE_WEBSOCKET);
 
   if (!mRequestedProtocolList.IsEmpty()) {
     rv = wsChannel->SetProtocol(mRequestedProtocolList);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   nsCOMPtr<nsIThreadRetargetableRequest> rr = do_QueryInterface(wsChannel);
   NS_ENSURE_TRUE(rr, NS_ERROR_FAILURE);
@@ -1977,26 +1984,34 @@ public:
   {
   }
 
   bool Notify(JSContext* aCx, Status aStatus) MOZ_OVERRIDE
   {
     MOZ_ASSERT(aStatus > workers::Running);
 
     if (aStatus >= Canceling) {
-      mWebSocketImpl->mWorkerShuttingDown = true;
+      {
+        MutexAutoLock lock(mWebSocketImpl->mMutex);
+        mWebSocketImpl->mWorkerShuttingDown = true;
+      }
+
       mWebSocketImpl->CloseConnection(nsIWebSocketChannel::CLOSE_GOING_AWAY);
     }
 
     return true;
   }
 
   bool Suspend(JSContext* aCx) MOZ_OVERRIDE
   {
-    mWebSocketImpl->mWorkerShuttingDown = true;
+    {
+      MutexAutoLock lock(mWebSocketImpl->mMutex);
+      mWebSocketImpl->mWorkerShuttingDown = true;
+    }
+
     mWebSocketImpl->CloseConnection(nsIWebSocketChannel::CLOSE_GOING_AWAY);
     return true;
   }
 
 private:
   WebSocketImpl* mWebSocketImpl;
 };
 
@@ -2546,26 +2561,37 @@ WebSocketImpl::SetLoadFlags(nsLoadFlags 
   // we won't change the load flags at all.
   return NS_OK;
 }
 
 namespace {
 
 class WorkerRunnableDispatcher MOZ_FINAL : public WorkerRunnable
 {
+  nsRefPtr<WebSocketImpl> mWebSocketImpl;
+
 public:
-  WorkerRunnableDispatcher(WorkerPrivate* aWorkerPrivate, nsIRunnable* aEvent)
+  WorkerRunnableDispatcher(WebSocketImpl* aImpl, WorkerPrivate* aWorkerPrivate,
+                           nsIRunnable* aEvent)
     : WorkerRunnable(aWorkerPrivate, WorkerThreadUnchangedBusyCount)
+    , mWebSocketImpl(aImpl)
     , mEvent(aEvent)
   {
   }
 
   bool WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
   {
     aWorkerPrivate->AssertIsOnWorkerThread();
+
+    // No messages when disconnected.
+    if (mWebSocketImpl->mDisconnectingOrDisconnected) {
+      NS_WARNING("Dispatching a WebSocket event after the disconnection!");
+      return true;
+    }
+
     aWorkerPrivate->ModifyBusyCountFromWorker(aCx, true);
     return !NS_FAILED(mEvent->Run());
   }
 
   void PostRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate, bool aRunResult)
   {
     aWorkerPrivate->ModifyBusyCountFromWorker(aCx, false);
   }
@@ -2591,36 +2617,32 @@ private:
 NS_IMETHODIMP
 WebSocketImpl::Dispatch(nsIRunnable* aEvent, uint32_t aFlags)
 {
   // If the target is the main-thread we can just dispatch the runnable.
   if (mIsMainThread) {
     return NS_DispatchToMainThread(aEvent);
   }
 
-  // No messages when disconnected.
-  if (mDisconnectingOrDisconnected) {
-    NS_WARNING("Dispatching a WebSocket event after the disconnection!");
-    return NS_OK;
-  }
-
+  // If the target is a worker, we have to use a custom WorkerRunnableDispatcher
+  // runnable.
+  nsRefPtr<WorkerRunnableDispatcher> event =
+    new WorkerRunnableDispatcher(this, mWorkerPrivate, aEvent);
+
+  MutexAutoLock lock(mMutex);
   if (mWorkerShuttingDown) {
     return NS_OK;
   }
 
   MOZ_ASSERT(mWorkerPrivate);
 
 #ifdef DEBUG
   MOZ_ASSERT(HasFeatureRegistered());
 #endif
 
-  // If the target is a worker, we have to use a custom WorkerRunnableDispatcher
-  // runnable.
-  nsRefPtr<WorkerRunnableDispatcher> event =
-    new WorkerRunnableDispatcher(mWorkerPrivate, aEvent);
   if (!event->Dispatch(nullptr)) {
     return NS_ERROR_FAILURE;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
--- a/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.cpp
+++ b/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.cpp
@@ -1662,24 +1662,40 @@ BluetoothServiceBluedroid::BondStateChan
 
   nsString signalName = bonded ? NS_LITERAL_STRING(DEVICE_PAIRED_ID)
                                : NS_LITERAL_STRING(DEVICE_UNPAIRED_ID);
 
   DistributeSignal(BluetoothSignal(signalName,
                                    NS_LITERAL_STRING(KEY_ADAPTER),
                                    BluetoothValue(propertiesArray)));
 
-  if (bonded && !sBondingRunnableArray.IsEmpty()) {
-    DispatchBluetoothReply(sBondingRunnableArray[0],
-                           BluetoothValue(true), EmptyString());
-    sBondingRunnableArray.RemoveElementAt(0);
-  } else if (!bonded && !sUnbondingRunnableArray.IsEmpty()) {
-    DispatchBluetoothReply(sUnbondingRunnableArray[0],
-                           BluetoothValue(true), EmptyString());
-    sUnbondingRunnableArray.RemoveElementAt(0);
+  if (aStatus == STATUS_SUCCESS) {
+    // Resolve existing pair/unpair promise when pair/unpair succeeded
+    if (bonded && !sBondingRunnableArray.IsEmpty()) {
+      DispatchBluetoothReply(sBondingRunnableArray[0],
+                             BluetoothValue(true), EmptyString());
+      sBondingRunnableArray.RemoveElementAt(0);
+    } else if (!bonded && !sUnbondingRunnableArray.IsEmpty()) {
+      DispatchBluetoothReply(sUnbondingRunnableArray[0],
+                             BluetoothValue(true), EmptyString());
+      sUnbondingRunnableArray.RemoveElementAt(0);
+    }
+  } else {
+    // Reject existing pair/unpair promise when pair/unpair failed
+    if (!bonded && !sBondingRunnableArray.IsEmpty()) {
+      DispatchBluetoothReply(sBondingRunnableArray[0],
+                             BluetoothValue(),
+                             NS_LITERAL_STRING("Pair Error"));
+      sBondingRunnableArray.RemoveElementAt(0);
+    } else if (bonded && !sUnbondingRunnableArray.IsEmpty()) {
+      DispatchBluetoothReply(sUnbondingRunnableArray[0],
+                             BluetoothValue(),
+                             NS_LITERAL_STRING("Unpair Error"));
+      sUnbondingRunnableArray.RemoveElementAt(0);
+    }
   }
 }
 
 void
 BluetoothServiceBluedroid::AclStateChangedNotification(
   BluetoothStatus aStatus, const nsAString& aRemoteBdAddr, bool aState)
 {
   MOZ_ASSERT(NS_IsMainThread());
--- a/dom/locales/en-US/chrome/plugins.properties
+++ b/dom/locales/en-US/chrome/plugins.properties
@@ -15,10 +15,14 @@ path_label=Path:
 version_label=Version:
 state_label=State:
 state_enabled=Enabled
 state_disabled=Disabled
 mimetype_label=MIME Type
 description_label=Description
 suffixes_label=Suffixes
 
+# GMP Plugins
 openH264_name=OpenH264 Video Codec provided by Cisco Systems, Inc.
 openH264_description=Play back web video and use video chats.
+
+eme-adobe_name=Primetime Content Decryption Module provided by Adobe Systems, Incorporated
+eme-adobe_description=Play back protected web video.
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -2953,17 +2953,17 @@ MediaDecoderStateMachine::FlushDecoding(
                "Should be on state machine or decode thread.");
   AssertCurrentThreadInMonitor();
 
   {
     // Put a task in the decode queue to abort any decoding operations.
     // The reader is not supposed to put any tasks to deliver samples into
     // the queue after this runs (unless we request another sample from it).
     RefPtr<nsIRunnable> task;
-    task = NS_NewRunnableMethod(mReader, &MediaDecoderReader::ResetDecode);
+    task = NS_NewRunnableMethod(this, &MediaDecoderStateMachine::ResetDecode);
 
     // Wait for the ResetDecode to run and for the decoder to abort
     // decoding operations and run any pending callbacks. This is
     // important, as we don't want any pending tasks posted to the task
     // queue by the reader to deliver any samples after we've posted the
     // reader Shutdown() task below, as the sample-delivery tasks will
     // keep video frames alive until after we've called Reader::Shutdown(),
     // and shutdown on B2G will fail as there are outstanding video frames
@@ -2974,16 +2974,35 @@ MediaDecoderStateMachine::FlushDecoding(
   }
 
   // We must reset playback so that all references to frames queued
   // in the state machine are dropped, else subsequent calls to Shutdown()
   // or ReleaseMediaResources() can fail on B2G.
   ResetPlayback();
 }
 
+void
+MediaDecoderStateMachine::ResetDecode()
+{
+  NS_ASSERTION(OnDecodeThread(), "Should be on decode thread.");
+
+  if (!mReader) {
+    return;
+  }
+
+  {
+    ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
+    if (mWaitingForDecoderSeek && !mCancelingSeek) {
+      mReader->CancelSeek();
+      mCancelingSeek = true;
+    }
+  }
+  mReader->ResetDecode();
+}
+
 void MediaDecoderStateMachine::RenderVideoFrame(VideoData* aData,
                                                 TimeStamp aTarget)
 {
   NS_ASSERTION(OnStateMachineThread() || OnDecodeThread(),
                "Should be on state machine or decode thread.");
   mDecoder->GetReentrantMonitor().AssertNotCurrentThreadIn();
 
   if (aData->mDuplicate) {
--- a/dom/media/MediaDecoderStateMachine.h
+++ b/dom/media/MediaDecoderStateMachine.h
@@ -417,16 +417,19 @@ public:
   }
 
   void OnWaitForDataRejected(WaitForDataRejectValue aRejection)
   {
     ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
     WaitRequestRef(aRejection.mType).Complete();
   }
 
+  // Resets all state related to decoding, emptying all buffers etc.
+  void ResetDecode();
+
 private:
   void AcquireMonitorAndInvokeDecodeError();
 
 protected:
   virtual ~MediaDecoderStateMachine();
 
   void AssertCurrentThreadInMonitor() const { mDecoder->GetReentrantMonitor().AssertCurrentThreadIn(); }
 
--- a/dom/media/PeerConnection.js
+++ b/dom/media/PeerConnection.js
@@ -800,19 +800,18 @@ RTCPeerConnection.prototype = {
     let sender = this._win.RTCRtpSender._create(this._win,
                                                 new RTCRtpSender(this, track,
                                                                  stream));
     this._senders.push({ sender: sender, stream: stream });
     return sender;
   },
 
   removeTrack: function(sender) {
-     // Bug 844295: Not implementing this functionality.
-     throw new this._win.DOMException("removeTrack not yet implemented",
-                                      "NotSupportedError");
+    this._checkClosed();
+    this._impl.removeTrack(sender.track);
   },
 
   _replaceTrack: function(sender, withTrack) {
     // TODO: Do a (sender._stream.getTracks().indexOf(track) < 0) check
     //       on both track args someday.
     //
     // The proposed API will be that both tracks must already be in the same
     // stream. However, since our MediaStreams currently are limited to one
@@ -1110,16 +1109,20 @@ PeerConnectionObserver.prototype = {
               candidate: candidate,
               sdpMid: mid,
               sdpMLineIndex: level
           }
       ));
     }
   },
 
+  onNegotiationNeeded: function() {
+    this.dispatchEvent(new this._win.Event("negotiationneeded"));
+  },
+
 
   // This method is primarily responsible for updating iceConnectionState.
   // This state is defined in the WebRTC specification as follows:
   //
   // iceConnectionState:
   // -------------------
   //   new           The ICE Agent is gathering addresses and/or waiting for
   //                 remote candidates to be supplied.
--- a/dom/media/eme/MediaKeySystemAccess.cpp
+++ b/dom/media/eme/MediaKeySystemAccess.cpp
@@ -116,17 +116,17 @@ MediaKeySystemAccess::GetKeySystemStatus
 
 #ifdef XP_WIN
   if ((aKeySystem.EqualsLiteral("com.adobe.access") ||
        aKeySystem.EqualsLiteral("com.adobe.primetime"))) {
     // Win Vista and later only.
     if (!IsVistaOrLater()) {
       return MediaKeySystemStatus::Cdm_not_supported;
     }
-    if (!Preferences::GetBool("media.eme.adobe-access.enabled", false)) {
+    if (!Preferences::GetBool("media.gmp-eme-adobe.enabled", false)) {
       return MediaKeySystemStatus::Cdm_disabled;
     }
     if (!HaveGMPFor(mps,
                     NS_ConvertUTF16toUTF8(aKeySystem),
                     NS_LITERAL_CSTRING(GMP_API_DECRYPTOR))) {
       return MediaKeySystemStatus::Cdm_not_installed;
     }
     return MediaKeySystemStatus::Available;
--- a/dom/media/tests/mochitest/dataChannel.js
+++ b/dom/media/tests/mochitest/dataChannel.js
@@ -12,159 +12,164 @@ function getBlobContent(blob) {
   return new Promise(resolve => {
     var reader = new FileReader();
     // Listen for 'onloadend' which will always be called after a success or failure
     reader.onloadend = event => resolve(event.target.result);
     reader.readAsText(blob);
   });
 }
 
-function addInitialDataChannel(chain) {
-  chain.insertBefore('PC_LOCAL_CREATE_OFFER', [
-    function PC_REMOTE_EXPECT_DATA_CHANNEL(test) {
-      test.pcRemote.expectDataChannel();
-    },
+var commandsCreateDataChannel = [
+  function PC_REMOTE_EXPECT_DATA_CHANNEL(test) {
+    test.pcRemote.expectDataChannel();
+  },
 
-    function PC_LOCAL_CREATE_DATA_CHANNEL(test) {
-      var channel = test.pcLocal.createDataChannel({});
-      is(channel.binaryType, "blob", channel + " is of binary type 'blob'");
-      is(channel.readyState, "connecting", channel + " is in state: 'connecting'");
+  function PC_LOCAL_CREATE_DATA_CHANNEL(test) {
+    var channel = test.pcLocal.createDataChannel({});
+    is(channel.binaryType, "blob", channel + " is of binary type 'blob'");
+    is(channel.readyState, "connecting", channel + " is in state: 'connecting'");
+
+    is(test.pcLocal.signalingState, STABLE,
+       "Create datachannel does not change signaling state");
+  }
+];
 
-      is(test.pcLocal.signalingState, STABLE,
-         "Create datachannel does not change signaling state");
-    }
-  ]);
+var commandsWaitForDataChannel = [
+  function PC_LOCAL_VERIFY_DATA_CHANNEL_STATE(test) {
+    return test.pcLocal.dataChannels[0].opened;
+  },
 
-  chain.insertBefore('PC_LOCAL_CHECK_MEDIA_TRACKS', [
-    function PC_LOCAL_VERIFY_DATA_CHANNEL_STATE(test) {
-      return test.pcLocal.dataChannels[0].opened;
-    },
+  function PC_REMOTE_VERIFY_DATA_CHANNEL_STATE(test) {
+    return test.pcRemote.nextDataChannel.then(channel => channel.opened);
+  },
+];
 
-    function PC_REMOTE_VERIFY_DATA_CHANNEL_STATE(test) {
-      return test.pcRemote.nextDataChannel.then(channel => channel.opened);
-    }
-  ]);
-  chain.removeAfter('PC_REMOTE_CHECK_ICE_CONNECTIONS');
-  chain.append([
-    function SEND_MESSAGE(test) {
-      var message = "Lorem ipsum dolor sit amet";
+var commandsCheckDataChannel = [
+  function SEND_MESSAGE(test) {
+    var message = "Lorem ipsum dolor sit amet";
+
+    return test.send(message).then(result => {
+      is(result.data, message, "Message correctly transmitted from pcLocal to pcRemote.");
+    });
+  },
 
-      return test.send(message).then(result => {
-        is(result.data, message, "Message correctly transmitted from pcLocal to pcRemote.");
-      });
-    },
-
-    function SEND_BLOB(test) {
-      var contents = ["At vero eos et accusam et justo duo dolores et ea rebum."];
-      var blob = new Blob(contents, { "type" : "text/plain" });
+  function SEND_BLOB(test) {
+    var contents = ["At vero eos et accusam et justo duo dolores et ea rebum."];
+    var blob = new Blob(contents, { "type" : "text/plain" });
 
-      return test.send(blob).then(result => {
-        ok(result.data instanceof Blob, "Received data is of instance Blob");
-        is(result.data.size, blob.size, "Received data has the correct size.");
+    return test.send(blob).then(result => {
+      ok(result.data instanceof Blob, "Received data is of instance Blob");
+      is(result.data.size, blob.size, "Received data has the correct size.");
 
-        return getBlobContent(result.data);
-      }).then(recv_contents =>
-              is(recv_contents, contents, "Received data has the correct content."));
-    },
+      return getBlobContent(result.data);
+    }).then(recv_contents =>
+            is(recv_contents, contents, "Received data has the correct content."));
+  },
 
-    function CREATE_SECOND_DATA_CHANNEL(test) {
-      return test.createDataChannel({ }).then(result => {
-        var sourceChannel = result.local;
-        var targetChannel = result.remote;
-        is(sourceChannel.readyState, "open", sourceChannel + " is in state: 'open'");
-        is(targetChannel.readyState, "open", targetChannel + " is in state: 'open'");
+  function CREATE_SECOND_DATA_CHANNEL(test) {
+    return test.createDataChannel({ }).then(result => {
+      var sourceChannel = result.local;
+      var targetChannel = result.remote;
+      is(sourceChannel.readyState, "open", sourceChannel + " is in state: 'open'");
+      is(targetChannel.readyState, "open", targetChannel + " is in state: 'open'");
 
-        is(targetChannel.binaryType, "blob", targetChannel + " is of binary type 'blob'");
-      });
-    },
+      is(targetChannel.binaryType, "blob", targetChannel + " is of binary type 'blob'");
+    });
+  },
 
-    function SEND_MESSAGE_THROUGH_LAST_OPENED_CHANNEL(test) {
-      var channels = test.pcRemote.dataChannels;
-      var message = "I am the Omega";
+  function SEND_MESSAGE_THROUGH_LAST_OPENED_CHANNEL(test) {
+    var channels = test.pcRemote.dataChannels;
+    var message = "I am the Omega";
 
-      return test.send(message).then(result => {
-        is(channels.indexOf(result.channel), channels.length - 1, "Last channel used");
-        is(result.data, message, "Received message has the correct content.");
-      });
-    },
+    return test.send(message).then(result => {
+      is(channels.indexOf(result.channel), channels.length - 1, "Last channel used");
+      is(result.data, message, "Received message has the correct content.");
+    });
+  },
 
 
-    function SEND_MESSAGE_THROUGH_FIRST_CHANNEL(test) {
-      var message = "Message through 1st channel";
-      var options = {
-        sourceChannel: test.pcLocal.dataChannels[0],
-        targetChannel: test.pcRemote.dataChannels[0]
-      };
+  function SEND_MESSAGE_THROUGH_FIRST_CHANNEL(test) {
+    var message = "Message through 1st channel";
+    var options = {
+      sourceChannel: test.pcLocal.dataChannels[0],
+      targetChannel: test.pcRemote.dataChannels[0]
+    };
 
-      return test.send(message, options).then(result => {
-        is(test.pcRemote.dataChannels.indexOf(result.channel), 0, "1st channel used");
-        is(result.data, message, "Received message has the correct content.");
-      });
-    },
+    return test.send(message, options).then(result => {
+      is(test.pcRemote.dataChannels.indexOf(result.channel), 0, "1st channel used");
+      is(result.data, message, "Received message has the correct content.");
+    });
+  },
 
 
-    function SEND_MESSAGE_BACK_THROUGH_FIRST_CHANNEL(test) {
-      var message = "Return a message also through 1st channel";
-      var options = {
-        sourceChannel: test.pcRemote.dataChannels[0],
-        targetChannel: test.pcLocal.dataChannels[0]
-      };
+  function SEND_MESSAGE_BACK_THROUGH_FIRST_CHANNEL(test) {
+    var message = "Return a message also through 1st channel";
+    var options = {
+      sourceChannel: test.pcRemote.dataChannels[0],
+      targetChannel: test.pcLocal.dataChannels[0]
+    };
 
-      return test.send(message, options).then(result => {
-        is(test.pcLocal.dataChannels.indexOf(result.channel), 0, "1st channel used");
-        is(result.data, message, "Return message has the correct content.");
-      });
-    },
+    return test.send(message, options).then(result => {
+      is(test.pcLocal.dataChannels.indexOf(result.channel), 0, "1st channel used");
+      is(result.data, message, "Return message has the correct content.");
+    });
+  },
 
-    function CREATE_NEGOTIATED_DATA_CHANNEL(test) {
-      var options = {
-        negotiated:true,
-        id: 5,
-        protocol: "foo/bar",
-        ordered: false,
-        maxRetransmits: 500
-      };
-      return test.createDataChannel(options).then(result => {
-        var sourceChannel2 = result.local;
-        var targetChannel2 = result.remote;
-        is(sourceChannel2.readyState, "open", sourceChannel2 + " is in state: 'open'");
-        is(targetChannel2.readyState, "open", targetChannel2 + " is in state: 'open'");
+  function CREATE_NEGOTIATED_DATA_CHANNEL(test) {
+    var options = {
+      negotiated:true,
+      id: 5,
+      protocol: "foo/bar",
+      ordered: false,
+      maxRetransmits: 500
+    };
+    return test.createDataChannel(options).then(result => {
+      var sourceChannel2 = result.local;
+      var targetChannel2 = result.remote;
+      is(sourceChannel2.readyState, "open", sourceChannel2 + " is in state: 'open'");
+      is(targetChannel2.readyState, "open", targetChannel2 + " is in state: 'open'");
 
-        is(targetChannel2.binaryType, "blob", targetChannel2 + " is of binary type 'blob'");
+      is(targetChannel2.binaryType, "blob", targetChannel2 + " is of binary type 'blob'");
 
-        is(sourceChannel2.id, options.id, sourceChannel2 + " id is:" + sourceChannel2.id);
-        var reliable = !options.ordered ? false : (options.maxRetransmits || options.maxRetransmitTime);
-        is(sourceChannel2.protocol, options.protocol, sourceChannel2 + " protocol is:" + sourceChannel2.protocol);
-        is(sourceChannel2.reliable, reliable, sourceChannel2 + " reliable is:" + sourceChannel2.reliable);
-        /*
-          These aren't exposed by IDL yet
-          is(sourceChannel2.ordered, options.ordered, sourceChannel2 + " ordered is:" + sourceChannel2.ordered);
-          is(sourceChannel2.maxRetransmits, options.maxRetransmits, sourceChannel2 + " maxRetransmits is:" +
-          sourceChannel2.maxRetransmits);
-          is(sourceChannel2.maxRetransmitTime, options.maxRetransmitTime, sourceChannel2 + " maxRetransmitTime is:" +
-          sourceChannel2.maxRetransmitTime);
-        */
+      is(sourceChannel2.id, options.id, sourceChannel2 + " id is:" + sourceChannel2.id);
+      var reliable = !options.ordered ? false : (options.maxRetransmits || options.maxRetransmitTime);
+      is(sourceChannel2.protocol, options.protocol, sourceChannel2 + " protocol is:" + sourceChannel2.protocol);
+      is(sourceChannel2.reliable, reliable, sourceChannel2 + " reliable is:" + sourceChannel2.reliable);
+      /*
+        These aren't exposed by IDL yet
+        is(sourceChannel2.ordered, options.ordered, sourceChannel2 + " ordered is:" + sourceChannel2.ordered);
+        is(sourceChannel2.maxRetransmits, options.maxRetransmits, sourceChannel2 + " maxRetransmits is:" +
+        sourceChannel2.maxRetransmits);
+        is(sourceChannel2.maxRetransmitTime, options.maxRetransmitTime, sourceChannel2 + " maxRetransmitTime is:" +
+        sourceChannel2.maxRetransmitTime);
+      */
 
-        is(targetChannel2.id, options.id, targetChannel2 + " id is:" + targetChannel2.id);
-        is(targetChannel2.protocol, options.protocol, targetChannel2 + " protocol is:" + targetChannel2.protocol);
-        is(targetChannel2.reliable, reliable, targetChannel2 + " reliable is:" + targetChannel2.reliable);
-        /*
-          These aren't exposed by IDL yet
-          is(targetChannel2.ordered, options.ordered, targetChannel2 + " ordered is:" + targetChannel2.ordered);
-          is(targetChannel2.maxRetransmits, options.maxRetransmits, targetChannel2 + " maxRetransmits is:" +
-          targetChannel2.maxRetransmits);
-          is(targetChannel2.maxRetransmitTime, options.maxRetransmitTime, targetChannel2 + " maxRetransmitTime is:" +
-          targetChannel2.maxRetransmitTime);
-        */
-      });
-    },
+      is(targetChannel2.id, options.id, targetChannel2 + " id is:" + targetChannel2.id);
+      is(targetChannel2.protocol, options.protocol, targetChannel2 + " protocol is:" + targetChannel2.protocol);
+      is(targetChannel2.reliable, reliable, targetChannel2 + " reliable is:" + targetChannel2.reliable);
+      /*
+        These aren't exposed by IDL yet
+        is(targetChannel2.ordered, options.ordered, targetChannel2 + " ordered is:" + targetChannel2.ordered);
+        is(targetChannel2.maxRetransmits, options.maxRetransmits, targetChannel2 + " maxRetransmits is:" +
+        targetChannel2.maxRetransmits);
+        is(targetChannel2.maxRetransmitTime, options.maxRetransmitTime, targetChannel2 + " maxRetransmitTime is:" +
+        targetChannel2.maxRetransmitTime);
+      */
+    });
+  },
 
-    function SEND_MESSAGE_THROUGH_LAST_OPENED_CHANNEL2(test) {
-      var channels = test.pcRemote.dataChannels;
-      var message = "I am the walrus; Goo goo g'joob";
+  function SEND_MESSAGE_THROUGH_LAST_OPENED_CHANNEL2(test) {
+    var channels = test.pcRemote.dataChannels;
+    var message = "I am the walrus; Goo goo g'joob";
 
-      return test.send(message).then(result => {
-        is(channels.indexOf(result.channel), channels.length - 1, "Last channel used");
-        is(result.data, message, "Received message has the correct content.");
-      });
-    }
-  ]);
+    return test.send(message).then(result => {
+      is(channels.indexOf(result.channel), channels.length - 1, "Last channel used");
+      is(result.data, message, "Received message has the correct content.");
+    });
+  }
+];
+
+function addInitialDataChannel(chain) {
+  chain.insertBefore('PC_LOCAL_CREATE_OFFER', commandsCreateDataChannel);
+  chain.insertBefore('PC_LOCAL_CHECK_MEDIA_TRACKS', commandsWaitForDataChannel);
+  chain.removeAfter('PC_REMOTE_CHECK_ICE_CONNECTIONS');
+  chain.append(commandsCheckDataChannel);
 }
--- a/dom/media/tests/mochitest/head.js
+++ b/dom/media/tests/mochitest/head.js
@@ -358,46 +358,68 @@ CommandChain.prototype = {
    * Add new commands to the end of the chain
    */
   append: function(commands) {
     this.commands = this.commands.concat(commands);
   },
 
   /**
    * Returns the index of the specified command in the chain.
+   * @param {start} Optional param specifying the index at which the search will
+   * start. If not specified, the search starts at index 0.
    */
-  indexOf: function(functionOrName) {
+  indexOf: function(functionOrName, start) {
+    start = start || 0;
     if (typeof functionOrName === 'string') {
-      return this.commands.findIndex(f => f.name === functionOrName);
+      var index = this.commands.slice(start).findIndex(f => f.name === functionOrName);
+      if (index !== -1) {
+        index += start;
+      }
+      return index;
     }
-    return this.commands.indexOf(functionOrName);
+    return this.commands.indexOf(functionOrName, start);
   },
 
   /**
    * Inserts the new commands after the specified command.
    */
   insertAfter: function(functionOrName, commands) {
     this._insertHelper(functionOrName, commands, 1);
   },
 
   /**
+   * Inserts the new commands after every occurrence of the specified command
+   */
+  insertAfterEach: function(functionOrName, commands) {
+    this._insertHelper(functionOrName, commands, 1, true);
+  },
+
+  /**
    * Inserts the new commands before the specified command.
    */
-  insertBefore: function(functionOrName, commands) {
-    this._insertHelper(functionOrName, commands, 0);
+  insertBefore: function(functionOrName, commands, all, start) {
+    this._insertHelper(functionOrName, commands, 0, all, start);
   },
 
-  _insertHelper: function(functionOrName, commands, delta) {
+  _insertHelper: function(functionOrName, commands, delta, all, start) {
     var index = this.indexOf(functionOrName);
-
-    if (index >= 0) {
-      this.commands = [].concat(
-        this.commands.slice(0, index + delta),
-        commands,
-        this.commands.slice(index + delta));
+    start = start || 0;
+    for (; index !== -1; index = this.indexOf(functionOrName, index)) {
+      if (!start) {
+        this.commands = [].concat(
+          this.commands.slice(0, index + delta),
+          commands,
+          this.commands.slice(index + delta));
+        if (!all) {
+          break;
+        }
+      } else {
+        start -= 1;
+      }
+      index += (commands.length + 1);
     }
   },
 
   /**
    * Removes the specified command, returns what was removed.
    */
   remove: function(functionOrName) {
     var index = this.indexOf(functionOrName);
@@ -455,17 +477,17 @@ CommandChain.prototype = {
     return oldCommands;
   },
 
   /**
    * Remove all commands whose name match the specified regex.
    */
   filterOut: function (id_match) {
     this.commands = this.commands.filter(c => !id_match.test(c.name));
-  }
+  },
 };
 
 
 function IsMacOSX10_6orOlder() {
   if (navigator.platform.indexOf("Mac") !== 0) {
     return false;
   }
 
--- a/dom/media/tests/mochitest/mochitest.ini
+++ b/dom/media/tests/mochitest/mochitest.ini
@@ -145,13 +145,37 @@ skip-if = toolkit == 'gonk' # b2g (Bug 1
 [test_peerConnection_twoAudioStreams.html]
 skip-if = toolkit == 'gonk' # b2g (Bug 1059867)
 [test_peerConnection_twoAudioVideoStreams.html]
 skip-if = (toolkit == 'gonk' || (e10s && debug)) # b2g (Bug 1059867) or fd exhaustion on e10s debug intermittent (Bug 1126078)
 [test_peerConnection_twoAudioVideoStreamsCombined.html]
 skip-if = (toolkit == 'gonk' || (e10s && debug)) # b2g (Bug 1059867) or fd exhaustion on e10s debug intermittent (Bug 1126078)
 [test_peerConnection_twoVideoStreams.html]
 skip-if = (toolkit == 'gonk' || (e10s && debug)) # b2g (Bug 1059867) or fd exhaustion on e10s debug intermittent (Bug 1126078)
-# Renegotiation is not yet supported (bug 1017888)
-#[test_peerConnection_addSecondAudioStream.html]
+[test_peerConnection_addSecondAudioStream.html]
+skip-if = toolkit == 'gonk' # b2g (Bug 1059867)
+[test_peerConnection_answererAddSecondAudioStream.html]
+skip-if = toolkit == 'gonk' # b2g (Bug 1059867)
+[test_peerConnection_removeAudioTrack.html]
+skip-if = toolkit == 'gonk' # b2g (Bug 1059867)
+[test_peerConnection_removeThenAddAudioTrack.html]
+skip-if = toolkit == 'gonk' # b2g (Bug 1059867)
+[test_peerConnection_addSecondVideoStream.html]
+skip-if = toolkit == 'gonk' # b2g (Bug 1059867)
+[test_peerConnection_removeVideoTrack.html]
+skip-if = toolkit == 'gonk' # b2g (Bug 1059867)
+[test_peerConnection_removeThenAddVideoTrack.html]
+skip-if = toolkit == 'gonk' # b2g (Bug 1059867)
+[test_peerConnection_addSecondAudioStreamNoBundle.html]
+skip-if = toolkit == 'gonk' # b2g (Bug 1059867)
+[test_peerConnection_removeThenAddAudioTrackNoBundle.html]
+skip-if = toolkit == 'gonk' # b2g (Bug 1059867)
+[test_peerConnection_addSecondVideoStreamNoBundle.html]
+skip-if = toolkit == 'gonk' # b2g (Bug 1059867)
+[test_peerConnection_removeThenAddVideoTrackNoBundle.html]
+skip-if = toolkit == 'gonk' # b2g (Bug 1059867)
+[test_peerConnection_addDataChannel.html]
+skip-if = toolkit == 'gonk' # b2g (Bug 1059867)
+[test_peerConnection_addDataChannelNoBundle.html]
+skip-if = toolkit == 'gonk' # b2g (Bug 1059867)
 
 # Bug 950317: Hack for making a cleanup hook after finishing all WebRTC cases
 [test_zmedia_cleanup.html]
--- a/dom/media/tests/mochitest/pc.js
+++ b/dom/media/tests/mochitest/pc.js
@@ -116,16 +116,22 @@ function removeVP8(sdp) {
   updated_sdp = updated_sdp.replace("RTP/SAVPF 120 126 97\r\n","RTP/SAVPF 126 97\r\n");
   updated_sdp = updated_sdp.replace("RTP/SAVPF 120 126\r\n","RTP/SAVPF 126\r\n");
   updated_sdp = updated_sdp.replace("a=rtcp-fb:120 nack\r\n","");
   updated_sdp = updated_sdp.replace("a=rtcp-fb:120 nack pli\r\n","");
   updated_sdp = updated_sdp.replace("a=rtcp-fb:120 ccm fir\r\n","");
   return updated_sdp;
 }
 
+var makeDefaultCommands = () => {
+  return [].concat(commandsPeerConnectionInitial,
+                   commandsGetUserMedia,
+                   commandsPeerConnectionOfferAnswer);
+};
+
 /**
  * This class handles tests for peer connections.
  *
  * @constructor
  * @param {object} [options={}]
  *        Optional options for the peer connection test
  * @param {object} [options.commands=commandsPeerConnection]
  *        Commands to run for the test
@@ -137,17 +143,17 @@ function removeVP8(sdp) {
  *        Configuration for the local peer connection instance
  * @param {object} [options.config_remote=undefined]
  *        Configuration for the remote peer connection instance. If not defined
  *        the configuration from the local instance will be used
  */
 function PeerConnectionTest(options) {
   // If no options are specified make it an empty object
   options = options || { };
-  options.commands = options.commands || commandsPeerConnection;
+  options.commands = options.commands || makeDefaultCommands();
   options.is_local = "is_local" in options ? options.is_local : true;
   options.is_remote = "is_remote" in options ? options.is_remote : true;
 
   if (typeof turnServers !== "undefined") {
     if ((!options.turn_disabled_local) && (turnServers.local)) {
       if (!options.hasOwnProperty("config_local")) {
         options.config_local = {};
       }
@@ -735,25 +741,33 @@ function PeerConnectionWrapper(label, co
 
   this.constraints = [ ];
   this.offerOptions = {};
   this.streams = [ ];
   this.mediaCheckers = [ ];
 
   this.dataChannels = [ ];
 
-  this.addStreamCounter = {audio: 0, video: 0 };
-
   this._local_ice_candidates = [];
   this._remote_ice_candidates = [];
   this.holdIceCandidates = new Promise(r => this.releaseIceCandidates = r);
   this.localRequiresTrickleIce = false;
   this.remoteRequiresTrickleIce = false;
   this.localMediaElements = [];
 
+  this.expectedLocalTrackTypesById = {};
+  this.expectedRemoteTrackTypesById = {};
+  this.observedRemoteTrackTypesById = {};
+
+  this.disableRtpCountChecking = false;
+
+  this.negotiationNeededFired = false;
+
+  this.iceCheckingRestartExpected = false;
+
   this.h264 = typeof h264 !== "undefined" ? true : false;
 
   info("Creating " + this);
   this._pc = new mozRTCPeerConnection(this.configuration);
 
   /**
    * Setup callback handlers
    */
@@ -764,44 +778,24 @@ function PeerConnectionWrapper(label, co
     isnot(typeof this._pc.iceConnectionState, "undefined",
           "iceConnectionState should not be undefined");
     info(this + ": oniceconnectionstatechange fired, new state is: " + this._pc.iceConnectionState);
     Object.keys(this.ice_connection_callbacks).forEach(name => {
       this.ice_connection_callbacks[name]();
     });
   };
 
-  /**
-   * Callback for native peer connection 'onaddstream' events.
-   *
-   * @param {Object} event
-   *        Event data which includes the stream to be added
-   */
-  this._pc.onaddstream = event => {
-    info(this + ": 'onaddstream' event fired for " + JSON.stringify(event.stream));
-
-    var type = '';
-    if (event.stream.getAudioTracks().length > 0) {
-      type = 'audio';
-      this.addStreamCounter.audio += this.countTracksInStreams('audio', [event.stream]);
-    }
-    if (event.stream.getVideoTracks().length > 0) {
-      type += 'video';
-      this.addStreamCounter.video += this.countTracksInStreams('video', [event.stream]);
-    }
-    this.attachMedia(event.stream, type, 'remote');
-  };
-
   createOneShotEventWrapper(this, this._pc, 'datachannel');
   this._pc.addEventListener('datachannel', e => {
     var wrapper = new DataChannelWrapper(e.channel, this);
     this.dataChannels.push(wrapper);
   });
 
   createOneShotEventWrapper(this, this._pc, 'signalingstatechange');
+  createOneShotEventWrapper(this, this._pc, 'negotiationneeded');
 }
 
 PeerConnectionWrapper.prototype = {
 
   /**
    * Returns the local description.
    *
    * @returns {object} The local description
@@ -883,30 +877,42 @@ PeerConnectionWrapper.prototype = {
         ok(this._pc.getSenders().find(sender => sender.track == stream.getVideoTracks()[0]),
            "addStream adds sender");
       } else {
         stream.getTracks().forEach(track => {
           var sender = this._pc.addTrack(track, stream);
           is(sender.track, track, "addTrack returns sender");
         });
       }
+
+      stream.getTracks().forEach(track => {
+        ok(track.id, "track has id");
+        ok(track.kind, "track has kind");
+        this.expectedLocalTrackTypesById[track.id] = track.kind;
+      });
     }
 
     var element = createMediaElement(type, this.label + '_' + side + this.streams.length);
     this.mediaCheckers.push(new MediaElementChecker(element));
     element.mozSrcObject = stream;
     element.play();
 
     // Store local media elements so that we can stop them when done.
     // Don't store remote ones because they should stop when the PC does.
     if (side === 'local') {
       this.localMediaElements.push(element);
     }
   },
 
+  removeSender : function(index) {
+    var sender = this._pc.getSenders()[index];
+    delete this.expectedLocalTrackTypesById[sender.track.id];
+    this._pc.removeTrack(sender);
+  },
+
   /**
    * Requests all the media streams as specified in the constrains property.
    *
    * @param {array} constraintsList
    *        Array of constraints for GUM calls
    */
   getAllUserMedia : function(constraintsList) {
     if (constraintsList.length === 0) {
@@ -1064,16 +1070,69 @@ PeerConnectionWrapper.prototype = {
       } else {
         ok(false, this + ": old signaling state " + oldstate + " missing in signaling transition array");
       }
       this.signalingStateLog.push(newstate);
     });
   },
 
   /**
+   * Checks whether a given track is expected, has not been observed yet, and
+   * is of the correct type. Then, moves the track from
+   * |expectedTrackTypesById| to |observedTrackTypesById|.
+   */
+  checkTrackIsExpected : function(track,
+                                  expectedTrackTypesById,
+                                  observedTrackTypesById) {
+    ok(expectedTrackTypesById[track.id], "track id " + track.id + " was expected");
+    ok(!observedTrackTypesById[track.id], "track id " + track.id + " was not yet observed");
+    var observedKind = track.kind;
+    var expectedKind = expectedTrackTypesById[track.id];
+    is(observedKind, expectedKind,
+        "track id " + track.id + " was of kind " +
+        observedKind + ", which matches " + expectedKind);
+    observedTrackTypesById[track.id] = expectedTrackTypesById[track.id];
+    delete expectedTrackTypesById[track.id];
+  },
+
+  setupAddStreamEventHandler: function() {
+    var resolveAllAddStreamEventsDone;
+
+    // checkMediaTracks waits on this promise later on in the test.
+    this.allAddStreamEventsDonePromise =
+      new Promise(resolve => resolveAllAddStreamEventsDone = resolve);
+
+    this._pc.addEventListener('addstream', event => {
+      info(this + ": 'onaddstream' event fired for " + JSON.stringify(event.stream));
+
+      // TODO(bug 1130185): We need to handle addtrack events once we start
+      // testing addTrack on pre-existing streams.
+
+      event.stream.getTracks().forEach(track => {
+        this.checkTrackIsExpected(track,
+                                  this.expectedRemoteTrackTypesById,
+                                  this.observedRemoteTrackTypesById);
+      });
+
+      if (Object.keys(this.expectedRemoteTrackTypesById).length === 0) {
+        resolveAllAddStreamEventsDone();
+      }
+
+      var type = '';
+      if (event.stream.getAudioTracks().length > 0) {
+        type = 'audio';
+      }
+      if (event.stream.getVideoTracks().length > 0) {
+        type += 'video';
+      }
+      this.attachMedia(event.stream, type, 'remote');
+    });
+  },
+
+  /**
    * Either adds a given ICE candidate right away or stores it to be added
    * later, depending on the state of the PeerConnection.
    *
    * @param {object} candidate
    *        The mozRTCIceCandidate to be added or stored
    */
   storeOrAddIceCandidate : function(candidate) {
     this._remote_ice_candidates.push(candidate);
@@ -1143,17 +1202,24 @@ PeerConnectionWrapper.prototype = {
    * appends the new state to an array for logging it later.
    */
   logIceConnectionState: function() {
     this.iceConnectionLog = [this._pc.iceConnectionState];
     this.ice_connection_callbacks.logIceStatus = () => {
       var newstate = this._pc.iceConnectionState;
       var oldstate = this.iceConnectionLog[this.iceConnectionLog.length - 1]
       if (Object.keys(iceStateTransitions).indexOf(oldstate) != -1) {
-        ok(iceStateTransitions[oldstate].indexOf(newstate) != -1, this + ": legal ICE state transition from " + oldstate + " to " + newstate);
+        if (this.iceCheckingRestartExpected) {
+          is(newstate, "checking",
+             "iceconnectionstate event \'" + newstate +
+             "\' matches expected state \'checking\'");
+          this.iceCheckingRestartExpected = false;
+        } else {
+          ok(iceStateTransitions[oldstate].indexOf(newstate) != -1, this + ": legal ICE state transition from " + oldstate + " to " + newstate);
+        }
       } else {
         ok(false, this + ": old ICE state " + oldstate + " missing in ICE transition array");
       }
       this.iceConnectionLog.push(newstate);
     };
   },
 
   /**
@@ -1279,77 +1345,55 @@ PeerConnectionWrapper.prototype = {
 
     if (offerToReceiveVideo) {
       return 1;
     } else {
       return 0;
     }
   },
 
-  /*
-   * Counts the amount of tracks of the given type in a set of streams.
-   *
-   * @param type audio|video
-   * @param streams
-   *        An array of streams (as returned by getLocalStreams()) to be
-   *        examined.
-   */
-  countTracksInStreams: function(type, streams) {
-    if (!Array.isArray(streams)) {
-      return 0;
-    }
-    var f = (type === 'video') ? "getVideoTracks" : "getAudioTracks";
+  checkLocalMediaTracks : function() {
+    var observedLocalTrackTypesById = {};
+    // We do not want to empty out this.expectedLocalTrackTypesById, so make a
+    // copy.
+    var expectedLocalTrackTypesById =
+      JSON.parse(JSON.stringify((this.expectedLocalTrackTypesById)));
+    info(this + " Checking local tracks " +
+         JSON.stringify(expectedLocalTrackTypesById));
+    this._pc.getLocalStreams().forEach(stream => {
+      stream.getTracks().forEach(track => {
+        this.checkTrackIsExpected(track,
+                                  expectedLocalTrackTypesById,
+                                  observedLocalTrackTypesById);
+      });
+    });
 
-    return streams.reduce((count, st) => {
-      return count + st[f]().length;
-    }, 0);
+    Object.keys(expectedLocalTrackTypesById).forEach(id => {
+      ok(false, this + " local id " + id + " was observed");
+    });
   },
 
   /**
    * Checks that we are getting the media tracks we expect.
    *
    * @param {object} constraints
    *        The media constraints of the remote peer connection object
    */
-  checkMediaTracks : function(remoteConstraints) {
-    var waitForExpectedTracks = type => {
-      var outstandingCount = this.countTracksInConstraint(type, remoteConstraints);
-      outstandingCount -= this.addStreamCounter[type];
-      if (outstandingCount <= 0) {
-        return Promise.resolve();
-      }
+  checkMediaTracks : function() {
+    this.checkLocalMediaTracks();
 
-      return new Promise(resolve => {
-        this._pc.addEventListener('addstream', e => {
-          outstandingCount -= this.countTracksInStreams(type, [e.stream]);
-          if (outstandingCount <= 0) {
-            resolve();
-          }
-        });
-      });
-    };
+    info(this + " Checking remote tracks " +
+         JSON.stringify(this.expectedRemoteTrackTypesById));
 
-    var checkTrackCounts = (side, streams, constraints) => {
-      ['audio', 'video'].forEach(type => {
-        var actual = this.countTracksInStreams(type, streams);
-        var expected = this.countTracksInConstraint(type, constraints);
-        is(actual, expected, this + ' has ' + actual + ' ' +
-           side + ' ' + type + ' tracks');
-      });
-    };
+    // No tracks are expected
+    if (Object.keys(this.expectedRemoteTrackTypesById).length === 0) {
+      return;
+    }
 
-    info(this + " checkMediaTracks() got called before onAddStream fired");
-    var checkPromise = Promise.all([
-      waitForExpectedTracks('audio'),
-      waitForExpectedTracks('video')
-    ]).then(() => {
-      checkTrackCounts('local', this._pc.getLocalStreams(), this.constraints);
-      checkTrackCounts('remote', this._pc.getRemoteStreams(), remoteConstraints);
-    });
-    return timerGuard(checkPromise, 60000, "onaddstream never fired");
+    return timerGuard(this.allAddStreamEventsDonePromise, 60000, "onaddstream never fired");
   },
 
   checkMsids: function() {
     var checkSdpForMsids = (desc, streams, side) => {
       streams.forEach(stream => {
         stream.getTracks().forEach(track => {
           // TODO(bug 1089798): Once DOMMediaStream has an id field, we
           // should be verifying that the SDP contains
@@ -1510,20 +1554,22 @@ PeerConnectionWrapper.prototype = {
               }
               if (res.remoteId) {
                 var rem = stats[res.remoteId];
                 ok(rem.isRemote, "Remote is rtcp");
                 ok(rem.remoteId == res.id, "Remote backlink match");
                 if(res.type == "outboundrtp") {
                   ok(rem.type == "inboundrtp", "Rtcp is inbound");
                   ok(rem.packetsReceived !== undefined, "Rtcp packetsReceived");
-                  ok(rem.packetsReceived <= res.packetsSent, "No more than sent");
                   ok(rem.packetsLost !== undefined, "Rtcp packetsLost");
                   ok(rem.bytesReceived >= rem.packetsReceived, "Rtcp bytesReceived");
-                  ok(rem.bytesReceived <= res.bytesSent, "No more than sent bytes");
+                  if (!this.disableRtpCountChecking) {
+                    ok(rem.packetsReceived <= res.packetsSent, "No more than sent packets");
+                    ok(rem.bytesReceived <= res.bytesSent, "No more than sent bytes");
+                  }
                   ok(rem.jitter !== undefined, "Rtcp jitter");
                   ok(rem.mozRtt !== undefined, "Rtcp rtt");
                   ok(rem.mozRtt >= 0, "Rtcp rtt " + rem.mozRtt + " >= 0");
                   ok(rem.mozRtt < 60000, "Rtcp rtt " + rem.mozRtt + " < 1 min");
                 } else {
                   ok(rem.type == "outboundrtp", "Rtcp is outbound");
                   ok(rem.packetsSent !== undefined, "Rtcp packetsSent");
                   // We may have received more than outdated Rtcp packetsSent
--- a/dom/media/tests/mochitest/templates.js
+++ b/dom/media/tests/mochitest/templates.js
@@ -58,27 +58,29 @@ function dumpSdp(test) {
     (typeof test.pcRemote.setLocalDescDate !== 'undefined') &&
     (typeof test.pcRemote.setLocalDescStableEventDate !== 'undefined')) {
     var delta = deltaSeconds(test.pcRemote.setLocalDescDate, test.pcRemote.setLocalDescStableEventDate);
     dump("Delay between pcRemote.setLocal <-> pcRemote.signalingStateStable: " + delta + "\n");
   }
 }
 
 function waitForIceConnected(test, pc) {
-  if (pc.isIceConnected()) {
-    info(pc + ": ICE connection state log: " + pc.iceConnectionLog);
-    ok(true, pc + ": ICE is in connected state");
-    return Promise.resolve();
-  }
+  if (!pc.iceCheckingRestartExpected) {
+    if (pc.isIceConnected()) {
+      info(pc + ": ICE connection state log: " + pc.iceConnectionLog);
+      ok(true, pc + ": ICE is in connected state");
+      return Promise.resolve();
+    }
 
-  if (!pc.isIceConnectionPending()) {
-    dumpSdp(test);
-    var details = pc + ": ICE is already in bad state: " + pc.iceConnectionState;
-    ok(false, details);
-    return Promise.reject(new Error(details));
+    if (!pc.isIceConnectionPending()) {
+      dumpSdp(test);
+      var details = pc + ": ICE is already in bad state: " + pc.iceConnectionState;
+      ok(false, details);
+      return Promise.reject(new Error(details));
+    }
   }
 
   return pc.waitForIceConnected()
     .then(() => {
       info(pc + ": ICE connection state log: " + pc.iceConnectionLog);
       ok(pc.isIceConnected(), pc + ": ICE switched to 'connected' state");
     });
 }
@@ -130,17 +132,19 @@ function checkTrackStats(pc, audio, outb
     }), msg + "3");
   });
 }
 
 // checks all stats combinations inbound/outbound, audio/video
 var checkAllTrackStats = pc =>
     Promise.all([0, 1, 2, 3].map(i => checkTrackStats(pc, i & 1, i & 2)));
 
-var commandsPeerConnection = [
+// Commands run once at the beginning of each test, even when performing a
+// renegotiation test.
+var commandsPeerConnectionInitial = [
   function PC_SETUP_SIGNALING_CLIENT(test) {
     if (test.steeplechase) {
       setTimeout(() => {
         ok(false, "PeerConnectionTest timed out");
         test.teardown();
       }, 30000);
       test.setupSignalingClient();
       test.registerSignalingCallback("ice_candidate", function (message) {
@@ -164,22 +168,22 @@ var commandsPeerConnection = [
   function PC_LOCAL_SETUP_SIGNALING_LOGGER(test) {
     test.pcLocal.logSignalingState();
   },
 
   function PC_REMOTE_SETUP_SIGNALING_LOGGER(test) {
     test.pcRemote.logSignalingState();
   },
 
-  function PC_LOCAL_GUM(test) {
-    return test.pcLocal.getAllUserMedia(test.pcLocal.constraints);
+  function PC_LOCAL_SETUP_ADDSTREAM_HANDLER(test) {
+    test.pcLocal.setupAddStreamEventHandler();
   },
 
-  function PC_REMOTE_GUM(test) {
-    return test.pcRemote.getAllUserMedia(test.pcRemote.constraints);
+  function PC_REMOTE_SETUP_ADDSTREAM_HANDLER(test) {
+    test.pcRemote.setupAddStreamEventHandler();
   },
 
   function PC_LOCAL_CHECK_INITIAL_SIGNALINGSTATE(test) {
     is(test.pcLocal.signalingState, STABLE,
        "Initial local signalingState is 'stable'");
   },
 
   function PC_REMOTE_CHECK_INITIAL_SIGNALINGSTATE(test) {
@@ -192,16 +196,44 @@ var commandsPeerConnection = [
        "Initial local ICE connection state is 'new'");
   },
 
   function PC_REMOTE_CHECK_INITIAL_ICE_STATE(test) {
     is(test.pcRemote.iceConnectionState, ICE_NEW,
        "Initial remote ICE connection state is 'new'");
   },
 
+];
+
+var commandsGetUserMedia = [
+  function PC_LOCAL_GUM(test) {
+    return test.pcLocal.getAllUserMedia(test.pcLocal.constraints);
+  },
+
+  function PC_REMOTE_GUM(test) {
+    return test.pcRemote.getAllUserMedia(test.pcRemote.constraints);
+  },
+];
+
+var commandsBeforeRenegotiation = [
+  function PC_LOCAL_SETUP_NEGOTIATION_CALLBACK(test) {
+    test.pcLocal.onnegotiationneeded = event => {
+      test.pcLocal.negotiationNeededFired = true;
+    };
+  },
+];
+
+var commandsAfterRenegotiation = [
+  function PC_LOCAL_CHECK_NEGOTIATION_CALLBACK(test) {
+    ok(test.pcLocal.negotiationNeededFired, "Expected negotiationneeded event");
+    test.pcLocal.negotiationNeededFired = false;
+  },
+];
+
+var commandsPeerConnectionOfferAnswer = [
   function PC_LOCAL_SETUP_ICE_HANDLER(test) {
     test.pcLocal.setupIceCandidateHandler(test);
     if (test.steeplechase) {
       test.pcLocal.endOfTrickleIce.then(() => {
         send_message({"type": "end_of_trickle_ice"});
       });
     }
   },
@@ -210,16 +242,66 @@ var commandsPeerConnection = [
     test.pcRemote.setupIceCandidateHandler(test);
     if (test.steeplechase) {
       test.pcRemote.endOfTrickleIce.then(() => {
         send_message({"type": "end_of_trickle_ice"});
       });
     }
   },
 
+  function PC_LOCAL_STEEPLECHASE_SIGNAL_EXPECTED_LOCAL_TRACKS(test) {
+    if (test.steeplechase) {
+      send_message({"type": "local_expected_tracks",
+                    "expected_tracks": test.pcLocal.expectedLocalTrackTypesById});
+    }
+  },
+
+  function PC_REMOTE_STEEPLECHASE_SIGNAL_EXPECTED_LOCAL_TRACKS(test) {
+    if (test.steeplechase) {
+      send_message({"type": "remote_expected_tracks",
+                    "expected_tracks": test.pcRemote.expectedLocalTrackTypesById});
+    }
+  },
+
+  function PC_LOCAL_GET_EXPECTED_REMOTE_TRACKS(test) {
+    if (test.steeplechase) {
+      return test.getSignalingMessage("remote_expected_tracks").then(
+          message => {
+            test.pcLocal.expectedRemoteTrackTypesById = message.expected_tracks;
+          });
+    } else {
+      // Deep copy, as similar to steeplechase as possible
+      test.pcLocal.expectedRemoteTrackTypesById =
+        JSON.parse(JSON.stringify((test.pcRemote.expectedLocalTrackTypesById)));
+    }
+
+    // Remove what we've already observed
+    Object.keys(test.pcLocal.observedRemoteTrackTypesById).forEach(id => {
+      delete test.pcLocal.expectedRemoteTrackTypesById[id];
+    });
+  },
+
+  function PC_LOCAL_GET_EXPECTED_REMOTE_TRACKS(test) {
+    if (test.steeplechase) {
+      return test.getSignalingMessage("local_expected_tracks").then(
+          message => {
+            test.pcRemote.expectedRemoteTrackTypesById = message.expected_tracks;
+          });
+    } else {
+      // Deep copy, as similar to steeplechase as possible
+      test.pcRemote.expectedRemoteTrackTypesById =
+        JSON.parse(JSON.stringify((test.pcLocal.expectedLocalTrackTypesById)));
+    }
+
+    // Remove what we've already observed
+    Object.keys(test.pcRemote.observedRemoteTrackTypesById).forEach(id => {
+      delete test.pcRemote.expectedRemoteTrackTypesById[id];
+    });
+  },
+
   function PC_LOCAL_CREATE_OFFER(test) {
     return test.createOffer(test.pcLocal).then(offer => {
       is(test.pcLocal.signalingState, STABLE,
          "Local create offer does not change signaling state");
     });
   },
 
   function PC_LOCAL_STEEPLECHASE_SIGNAL_OFFER(test) {
@@ -385,21 +467,21 @@ var commandsPeerConnection = [
     return waitForAnIceCandidate(test.pcLocal);
   },
 
   function PC_REMOTE_VERIFY_ICE_GATHERING(test) {
     return waitForAnIceCandidate(test.pcRemote);
   },
 
   function PC_LOCAL_CHECK_MEDIA_TRACKS(test) {
-    return test.pcLocal.checkMediaTracks(test._answer_constraints);
+    return test.pcLocal.checkMediaTracks();
   },
 
   function PC_REMOTE_CHECK_MEDIA_TRACKS(test) {
-    return test.pcRemote.checkMediaTracks(test._offer_constraints);
+    return test.pcRemote.checkMediaTracks();
   },
 
   function PC_LOCAL_CHECK_MEDIA_FLOW_PRESENT(test) {
     return test.pcLocal.checkMediaFlowPresent();
   },
 
   function PC_REMOTE_CHECK_MEDIA_FLOW_PRESENT(test) {
     return test.pcRemote.checkMediaFlowPresent();
@@ -463,8 +545,37 @@ var commandsPeerConnection = [
 
   function PC_LOCAL_CHECK_STATS(test) {
     return checkAllTrackStats(test.pcLocal);
   },
   function PC_REMOTE_CHECK_STATS(test) {
     return checkAllTrackStats(test.pcRemote);
   }
 ];
+
+function PC_LOCAL_REMOVE_BUNDLE_FROM_OFFER(test) {
+  test.originalOffer.sdp = test.originalOffer.sdp.replace(
+      /a=group:BUNDLE .*\r\n/g,
+      ""
+      );
+  info("Updated no bundle offer: " + JSON.stringify(test.originalOffer));
+};
+
+var addRenegotiation = (chain, commands, checks) => {
+  chain.append(commandsBeforeRenegotiation);
+  chain.append(commands);
+  chain.append(commandsAfterRenegotiation);
+  chain.append(commandsPeerConnectionOfferAnswer);
+  if (checks) {
+    chain.append(checks);
+  }
+};
+
+var addRenegotiationAnswerer = (chain, commands, checks) => {
+  chain.append(function SWAP_PC_LOCAL_PC_REMOTE(test) {
+    var temp = test.pcLocal;
+    test.pcLocal = test.pcRemote;
+    test.pcRemote = temp;
+  });
+  addRenegotiation(chain, commands, checks);
+};
+
+
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/test_peerConnection_addDataChannel.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <script type="application/javascript" src="pc.js"></script>
+</head>
+<body>
+<pre id="test">
+<script type="application/javascript">
+  createHTML({
+    bug: "1017888",
+    title: "Renegotiation: add DataChannel"
+  });
+
+  var test;
+  runNetworkTest(function (options) {
+    test = new PeerConnectionTest(options);
+    addRenegotiation(test.chain,
+                     commandsCreateDataChannel,
+                     commandsCheckDataChannel);
+
+    // Insert before the second PC_LOCAL_CHECK_MEDIA_TRACKS
+    test.chain.insertBefore('PC_LOCAL_CHECK_MEDIA_TRACKS',
+                            commandsWaitForDataChannel,
+                            false,
+                            1);
+
+    test.setMediaConstraints([{audio: true}], [{audio: true}]);
+    test.run();
+  });
+
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/test_peerConnection_addDataChannelNoBundle.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <script type="application/javascript" src="pc.js"></script>
+</head>
+<body>
+<pre id="test">
+<script type="application/javascript">
+  createHTML({
+    bug: "1017888",
+    title: "Renegotiation: add DataChannel"
+  });
+
+  var test;
+  runNetworkTest(function (options) {
+    test = new PeerConnectionTest(options);
+    addRenegotiation(test.chain,
+                     commandsCreateDataChannel.concat(
+                       [
+                         function PC_LOCAL_EXPECT_ICE_CHECKING(test) {
+                           test.pcLocal.iceCheckingRestartExpected = true;
+                         },
+                         function PC_REMOTE_EXPECT_ICE_CHECKING(test) {
+                           test.pcRemote.iceCheckingRestartExpected = true;
+                         },
+                       ]
+                      ),
+                     commandsCheckDataChannel);
+
+    test.chain.insertAfterEach('PC_LOCAL_CREATE_OFFER',
+                              PC_LOCAL_REMOVE_BUNDLE_FROM_OFFER);
+
+    // Insert before the second PC_LOCAL_CHECK_MEDIA_TRACKS
+    test.chain.insertBefore('PC_LOCAL_CHECK_MEDIA_TRACKS',
+                            commandsWaitForDataChannel,
+                            false,
+                            1);
+
+    test.setMediaConstraints([{audio: true}], [{audio: true}]);
+    test.run();
+  });
+
+</script>
+</pre>
+</body>
+</html>
--- a/dom/media/tests/mochitest/test_peerConnection_addSecondAudioStream.html
+++ b/dom/media/tests/mochitest/test_peerConnection_addSecondAudioStream.html
@@ -2,58 +2,33 @@
 <html>
 <head>
   <script type="application/javascript" src="pc.js"></script>
 </head>
 <body>
 <pre id="test">
 <script type="application/javascript">
   createHTML({
-    bug: "1091242",
+    bug: "1017888",
     title: "Renegotiation: add second audio stream"
   });
 
   var test;
   runNetworkTest(function (options) {
     test = new PeerConnectionTest(options);
-    test.chain.append([
-      function PC_LOCAL_SETUP_NEGOTIATION_CALLBACK(test) {
-        test.pcLocal.onNegotiationneededFired = false;
-        test.pcLocal._pc.onnegotiationneeded = anEvent => {
-          info("pcLocal.onnegotiationneeded fired");
-          test.pcLocal.onNegotiationneededFired = true;
-        };
-      },
-      function PC_LOCAL_ADD_SECOND_STREAM(test) {
-        return test.pcLocal.getAllUserMedia([{audio: true}]);
-      },
-      function PC_LOCAL_CREATE_NEW_OFFER(test) {
-        ok(test.pcLocal.onNegotiationneededFired, "onnegotiationneeded");
-        return test.createOffer(test.pcLocal).then(offer => {
-          test._new_offer = offer;
-        });
-      },
-      function PC_LOCAL_SET_NEW_LOCAL_DESCRIPTION(test) {
-        return test.setLocalDescription(test.pcLocal, test._new_offer, HAVE_LOCAL_OFFER);
-      },
-      function PC_REMOTE_SET_NEW_REMOTE_DESCRIPTION(test) {
-        return test.setRemoteDescription(test.pcRemote, test._new_offer, HAVE_REMOTE_OFFER);
-      },
-      function PC_REMOTE_CREATE_NEW_ANSWER(test) {
-        return test.createAnswer(test.pcRemote).then(answer => {
-          test._new_answer = answer;
-        });
-      },
-      function PC_REMOTE_SET_NEW_LOCAL_DESCRIPTION(test) {
-        return test.setLocalDescription(test.pcRemote, test._new_answer, STABLE);
-      },
-      function PC_LOCAL_SET_NEW_REMOTE_DESCRIPTION(test) {
-        return test.setRemoteDescription(test.pcLocal, test._new_answer, STABLE);
-      }
-      // TODO(bug 1093835): figure out how to verify if media flows through the new stream
-    ]);
+    addRenegotiation(test.chain,
+      [
+        function PC_LOCAL_ADD_SECOND_STREAM(test) {
+          test.setMediaConstraints([{audio: true}, {audio: true}],
+                                   [{audio: true}]);
+          return test.pcLocal.getAllUserMedia([{audio: true}]);
+        },
+      ]
+    );
+
+    // TODO(bug 1093835): figure out how to verify if media flows through the new stream
     test.setMediaConstraints([{audio: true}], [{audio: true}]);
     test.run();
   });
 </script>
 </pre>
 </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/test_peerConnection_addSecondAudioStreamNoBundle.html
@@ -0,0 +1,43 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <script type="application/javascript" src="pc.js"></script>
+</head>
+<body>
+<pre id="test">
+<script type="application/javascript">
+  createHTML({
+    bug: "1017888",
+    title: "Renegotiation: add second audio stream, no bundle"
+  });
+
+  var test;
+  runNetworkTest(function (options) {
+    test = new PeerConnectionTest(options);
+    addRenegotiation(test.chain,
+      [
+        function PC_LOCAL_ADD_SECOND_STREAM(test) {
+          test.setMediaConstraints([{audio: true}, {audio: true}],
+                                   [{audio: true}]);
+          // Since this is a NoBundle variant, adding a track will cause us to
+          // go back to checking.
+          test.pcLocal.iceCheckingRestartExpected = true;
+          return test.pcLocal.getAllUserMedia([{audio: true}]);
+        },
+        function PC_REMOTE_EXPECT_ICE_CHECKING(test) {
+          test.pcRemote.iceCheckingRestartExpected = true;
+        },
+      ]
+    );
+
+    test.chain.insertAfterEach('PC_LOCAL_CREATE_OFFER',
+                              PC_LOCAL_REMOVE_BUNDLE_FROM_OFFER);
+
+    // TODO(bug 1093835): figure out how to verify if media flows through the new stream
+    test.setMediaConstraints([{audio: true}], [{audio: true}]);
+    test.run();
+  });
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/test_peerConnection_addSecondVideoStream.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <script type="application/javascript" src="pc.js"></script>
+</head>
+<body>
+<pre id="test">
+<script type="application/javascript">
+  createHTML({
+    bug: "1017888",
+    title: "Renegotiation: add second video stream"
+  });
+
+  var test;
+  runNetworkTest(function (options) {
+    test = new PeerConnectionTest(options);
+    addRenegotiation(test.chain,
+      [
+        function PC_LOCAL_ADD_SECOND_STREAM(test) {
+          test.setMediaConstraints([{video: true}, {video: true}],
+                                   [{video: true}]);
+          return test.pcLocal.getAllUserMedia([{video: true}]);
+        },
+      ]
+    );
+
+    // TODO(bug 1093835): figure out how to verify if media flows through the new stream
+    test.setMediaConstraints([{video: true}], [{video: true}]);
+    test.run();
+  });
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/test_peerConnection_addSecondVideoStreamNoBundle.html
@@ -0,0 +1,43 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <script type="application/javascript" src="pc.js"></script>
+</head>
+<body>
+<pre id="test">
+<script type="application/javascript">
+  createHTML({
+    bug: "1017888",
+    title: "Renegotiation: add second video stream, no bundle"
+  });
+
+  var test;
+  runNetworkTest(function (options) {
+    test = new PeerConnectionTest(options);
+    addRenegotiation(test.chain,
+      [
+        function PC_LOCAL_ADD_SECOND_STREAM(test) {
+          test.setMediaConstraints([{video: true}, {video: true}],
+                                   [{video: true}]);
+          // Since this is a NoBundle variant, adding a track will cause us to
+          // go back to checking.
+          test.pcLocal.iceCheckingRestartExpected = true;
+          return test.pcLocal.getAllUserMedia([{video: true}]);
+        },
+        function PC_REMOTE_EXPECT_ICE_CHECKING(test) {
+          test.pcRemote.iceCheckingRestartExpected = true;
+        },
+      ]
+    );
+
+    test.chain.insertAfterEach('PC_LOCAL_CREATE_OFFER',
+                              PC_LOCAL_REMOVE_BUNDLE_FROM_OFFER);
+
+    // TODO(bug 1093835): figure out how to verify if media flows through the new stream
+    test.setMediaConstraints([{video: true}], [{video: true}]);
+    test.run();
+  });
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/test_peerConnection_answererAddSecondAudioStream.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <script type="application/javascript" src="pc.js"></script>
+</head>
+<body>
+<pre id="test">
+<script type="application/javascript">
+  createHTML({
+    bug: "1017888",
+    title: "Renegotiation: answerer adds second audio stream"
+  });
+
+  var test;
+  runNetworkTest(function (options) {
+    test = new PeerConnectionTest(options);
+    addRenegotiationAnswerer(test.chain,
+      [
+        function PC_LOCAL_ADD_SECOND_STREAM(test) {
+          test.setMediaConstraints([{audio: true}, {audio: true}],
+                                   [{audio: true}]);
+          return test.pcLocal.getAllUserMedia([{audio: true}]);
+        },
+      ]
+    );
+
+    test.setMediaConstraints([{audio: true}], [{audio: true}]);
+    test.run();
+  });
+</script>
+</pre>
+</body>
+</html>
+
--- a/dom/media/tests/mochitest/test_peerConnection_basicAudioVideoNoBundle.html
+++ b/dom/media/tests/mochitest/test_peerConnection_basicAudioVideoNoBundle.html
@@ -10,25 +10,17 @@
     bug: "1016476",
     title: "Basic audio/video peer connection with no Bundle"
   });
 
   runNetworkTest(options => {
     var test = new PeerConnectionTest(options);
     test.chain.insertAfter(
       'PC_LOCAL_CREATE_OFFER',
-      [
-        function PC_LOCAL_REMOVE_BUNDLE_FROM_OFFER(test) {
-          test.originalOffer.sdp = test.originalOffer.sdp.replace(
-              /a=group:BUNDLE .*\r\n/g,
-            ""
-          );
-          info("Updated no bundle offer: " + JSON.stringify(test.originalOffer));
-        }
-      ]);
+      [PC_LOCAL_REMOVE_BUNDLE_FROM_OFFER]);
     test.setMediaConstraints([{audio: true}, {video: true}],
                              [{audio: true}, {video: true}]);
     test.run();
   });
 </script>
 </pre>
 </body>
 </html>
--- a/dom/media/tests/mochitest/test_peerConnection_capturedVideo.html
+++ b/dom/media/tests/mochitest/test_peerConnection_capturedVideo.html
@@ -26,17 +26,20 @@ runNetworkTest(function() {
   test.setOfferOptions({ offerToReceiveVideo: false,
                          offerToReceiveAudio: false });
   test.chain.insertAfter("PC_LOCAL_GUM", [
     function PC_LOCAL_CAPTUREVIDEO(test) {
       return metadataLoaded
         .then(() => {
           var stream = v1.mozCaptureStreamUntilEnded();
           is(stream.getTracks().length, 2, "Captured stream has 2 tracks");
-          stream.getTracks().forEach(tr => test.pcLocal._pc.addTrack(tr, stream));
+          stream.getTracks().forEach(tr => {
+            test.pcLocal._pc.addTrack(tr, stream);
+            test.pcLocal.expectedLocalTrackTypesById[tr.id] = tr.kind;
+          });
           test.pcLocal.constraints = [{ video: true, audio:true }]; // fool tests
         });
     }
   ]);
   test.chain.removeAfter("PC_REMOTE_CHECK_MEDIA_FLOW_PRESENT");
   test.run();
 });
 </script>
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/test_peerConnection_removeAudioTrack.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <script type="application/javascript" src="pc.js"></script>
+</head>
+<body>
+<pre id="test">
+<script type="application/javascript">
+  createHTML({
+    bug: "1017888",
+    title: "Renegotiation: remove audio track"
+  });
+
+  var test;
+  runNetworkTest(function (options) {
+    test = new PeerConnectionTest(options);
+    addRenegotiation(test.chain,
+      [
+        function PC_LOCAL_REMOVE_AUDIO_TRACK(test) {
+          test.setOfferOptions({ offerToReceiveAudio: true });
+          test.setMediaConstraints([], [{audio: true}]);
+          return test.pcLocal.removeSender(0);
+        },
+      ]
+    );
+
+    // TODO(bug 1093835): figure out how to verify that media stopped flowing from pcLocal
+
+    test.setMediaConstraints([{audio: true}], [{audio: true}]);
+    test.run();
+  });
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/test_peerConnection_removeThenAddAudioTrack.html
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <script type="application/javascript" src="pc.js"></script>
+</head>
+<body>
+<pre id="test">
+<script type="application/javascript">
+  createHTML({
+    bug: "1017888",
+    title: "Renegotiation: remove then add audio track"
+  });
+
+  var test;
+  runNetworkTest(function (options) {
+    test = new PeerConnectionTest(options);
+    addRenegotiation(test.chain,
+      [
+        function PC_LOCAL_REMOVE_AUDIO_TRACK(test) {
+          return test.pcLocal.removeSender(0);
+        },
+        function PC_LOCAL_ADD_AUDIO_TRACK(test) {
+          // The new track's pipeline will start with a packet count of
+          // 0, but the remote side will keep its old pipeline and packet
+          // count.
+          test.pcLocal.disableRtpCountChecking = true;
+          return test.pcLocal.getAllUserMedia([{audio: true}]);
+        },
+      ]
+    );
+
+    // TODO(bug 1093835): figure out how to verify if media flows through the new stream
+    test.setMediaConstraints([{audio: true}], [{audio: true}]);
+    test.run();
+  });
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/test_peerConnection_removeThenAddAudioTrackNoBundle.html
@@ -0,0 +1,42 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <script type="application/javascript" src="pc.js"></script>
+</head>
+<body>
+<pre id="test">
+<script type="application/javascript">
+  createHTML({
+    bug: "1017888",
+    title: "Renegotiation: remove then add audio track"
+  });
+
+  var test;
+  runNetworkTest(function (options) {
+    test = new PeerConnectionTest(options);
+    addRenegotiation(test.chain,
+      [
+        function PC_LOCAL_REMOVE_AUDIO_TRACK(test) {
+          // The new track's pipeline will start with a packet count of
+          // 0, but the remote side will keep its old pipeline and packet
+          // count.
+          test.pcLocal.disableRtpCountChecking = true;
+          return test.pcLocal.removeSender(0);
+        },
+        function PC_LOCAL_ADD_AUDIO_TRACK(test) {
+          return test.pcLocal.getAllUserMedia([{audio: true}]);
+        },
+      ]
+    );
+
+    test.chain.insertAfterEach('PC_LOCAL_CREATE_OFFER',
+                              PC_LOCAL_REMOVE_BUNDLE_FROM_OFFER);
+
+    // TODO(bug 1093835): figure out how to verify if media flows through the new stream
+    test.setMediaConstraints([{audio: true}], [{audio: true}]);
+    test.run();
+  });
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/test_peerConnection_removeThenAddVideoTrack.html
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <script type="application/javascript" src="pc.js"></script>
+</head>
+<body>
+<pre id="test">
+<script type="application/javascript">
+  createHTML({
+    bug: "1017888",
+    title: "Renegotiation: remove then add video track"
+  });
+
+  var test;
+  runNetworkTest(function (options) {
+    test = new PeerConnectionTest(options);
+    addRenegotiation(test.chain,
+      [
+        function PC_LOCAL_REMOVE_AUDIO_TRACK(test) {
+          // The new track's pipeline will start with a packet count of
+          // 0, but the remote side will keep its old pipeline and packet
+          // count.
+          test.pcLocal.disableRtpCountChecking = true;
+          return test.pcLocal.removeSender(0);
+        },
+        function PC_LOCAL_ADD_AUDIO_TRACK(test) {
+          return test.pcLocal.getAllUserMedia([{video: true}]);
+        },
+      ]
+    );
+
+    // TODO(bug 1093835): figure out how to verify if media flows through the new stream
+    test.setMediaConstraints([{video: true}], [{video: true}]);
+    test.run();
+  });
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/test_peerConnection_removeThenAddVideoTrackNoBundle.html
@@ -0,0 +1,42 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <script type="application/javascript" src="pc.js"></script>
+</head>
+<body>
+<pre id="test">
+<script type="application/javascript">
+  createHTML({
+    bug: "1017888",
+    title: "Renegotiation: remove then add video track, no bundle"
+  });
+
+  var test;
+  runNetworkTest(function (options) {
+    test = new PeerConnectionTest(options);
+    addRenegotiation(test.chain,
+      [
+        function PC_LOCAL_REMOVE_AUDIO_TRACK(test) {
+          // The new track's pipeline will start with a packet count of
+          // 0, but the remote side will keep its old pipeline and packet
+          // count.
+          test.pcLocal.disableRtpCountChecking = true;
+          return test.pcLocal.removeSender(0);
+        },
+        function PC_LOCAL_ADD_AUDIO_TRACK(test) {
+          return test.pcLocal.getAllUserMedia([{video: true}]);
+        },
+      ]
+    );
+
+    test.chain.insertAfterEach('PC_LOCAL_CREATE_OFFER',
+                              PC_LOCAL_REMOVE_BUNDLE_FROM_OFFER);
+
+    // TODO(bug 1093835): figure out how to verify if media flows through the new stream
+    test.setMediaConstraints([{video: true}], [{video: true}]);
+    test.run();
+  });
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/test_peerConnection_removeVideoTrack.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <script type="application/javascript" src="pc.js"></script>
+</head>
+<body>
+<pre id="test">
+<script type="application/javascript">
+  createHTML({
+    bug: "1017888",
+    title: "Renegotiation: remove video track"
+  });
+
+  var test;
+  runNetworkTest(function (options) {
+    test = new PeerConnectionTest(options);
+    addRenegotiation(test.chain,
+      [
+        function PC_LOCAL_REMOVE_VIDEO_TRACK(test) {
+          test.setOfferOptions({ offerToReceiveVideo: true });
+          test.setMediaConstraints([], [{video: true}]);
+          return test.pcLocal.removeSender(0);
+        },
+      ]
+    );
+
+    // TODO(bug 1093835): figure out how to verify that media stopped flowing from pcLocal
+
+    test.setMediaConstraints([{video: true}], [{video: true}]);
+    test.run();
+  });
+</script>
+</pre>
+</body>
+</html>
--- a/dom/plugins/ipc/PluginInstanceParent.cpp
+++ b/dom/plugins/ipc/PluginInstanceParent.cpp
@@ -18,16 +18,18 @@
 #include "npfunctions.h"
 #include "nsAutoPtr.h"
 #include "gfxASurface.h"
 #include "gfxContext.h"
 #include "gfxPlatform.h"
 #include "gfxSharedImageSurface.h"
 #include "nsNPAPIPluginInstance.h"
 #include "nsPluginInstanceOwner.h"
+#include "nsFocusManager.h"
+#include "nsIDOMElement.h"
 #ifdef MOZ_X11
 #include "gfxXlibSurface.h"
 #endif
 #include "gfxContext.h"
 #include "gfxColor.h"
 #include "gfxUtils.h"
 #include "mozilla/gfx/2D.h"
 #include "Layers.h"
@@ -40,20 +42,16 @@
 #endif
 
 #if defined(OS_WIN)
 #include <windowsx.h>
 #include "gfxWindowsPlatform.h"
 #include "mozilla/plugins/PluginSurfaceParent.h"
 #include "nsClassHashtable.h"
 #include "nsHashKeys.h"
-// Plugin focus event for widget.
-extern const wchar_t* kOOPPPluginFocusEventId;
-UINT gOOPPPluginFocusEvent =
-    RegisterWindowMessage(kOOPPPluginFocusEventId);
 extern const wchar_t* kFlashFullscreenClass;
 #elif defined(MOZ_WIDGET_GTK)
 #include <gdk/gdk.h>
 #elif defined(XP_MACOSX)
 #include <ApplicationServices/ApplicationServices.h>
 #endif // defined(XP_MACOSX)
 
 using namespace mozilla::plugins;
@@ -1784,30 +1782,28 @@ PluginInstanceParent::PluginWindowHookPr
 
 void
 PluginInstanceParent::SubclassPluginWindow(HWND aWnd)
 {
     if ((aWnd && mPluginHWND == aWnd) || (!aWnd && mPluginHWND)) {
         return;
     }
 
-#if defined(XP_WIN)
     if (XRE_GetProcessType() == GeckoProcessType_Content) {
         if (!aWnd) {
             NS_WARNING("PluginInstanceParent::SubclassPluginWindow unexpected null window");
             return;
         }
         mPluginHWND = aWnd; // now a remote window, we can't subclass this
         mPluginWndProc = nullptr;
         // Note sPluginInstanceList wil delete 'this' if we do not remove
         // it on shutdown.
         sPluginInstanceList->Put((void*)mPluginHWND, this);
         return;
     }
-#endif
 
     NS_ASSERTION(!(mPluginHWND && aWnd != mPluginHWND),
         "PluginInstanceParent::SubclassPluginWindow hwnd is not our window!");
 
     mPluginHWND = aWnd;
     mPluginWndProc =
         (WNDPROC)::SetWindowLongPtrA(mPluginHWND, GWLP_WNDPROC,
             reinterpret_cast<LONG_PTR>(PluginWindowHookProc));
@@ -1816,33 +1812,31 @@ PluginInstanceParent::SubclassPluginWind
         "PluginInstanceParent::SubclassPluginWindow failed to set subclass!");
     NS_ASSERTION(bRes,
         "PluginInstanceParent::SubclassPluginWindow failed to set prop!");
 }
 
 void
 PluginInstanceParent::UnsubclassPluginWindow()
 {
-#if defined(XP_WIN)
     if (XRE_GetProcessType() == GeckoProcessType_Content) {
         if (mPluginHWND) {
             // Remove 'this' from the plugin list safely
             nsAutoPtr<PluginInstanceParent> tmp;
             MOZ_ASSERT(sPluginInstanceList);
             sPluginInstanceList->RemoveAndForget((void*)mPluginHWND, tmp);
             tmp.forget();
             if (!sPluginInstanceList->Count()) {
                 delete sPluginInstanceList;
                 sPluginInstanceList = nullptr;
             }
         }
         mPluginHWND = nullptr;
         return;
     }
-#endif
 
     if (mPluginHWND && mPluginWndProc) {
         ::SetWindowLongPtrA(mPluginHWND, GWLP_WNDPROC,
                             reinterpret_cast<LONG_PTR>(mPluginWndProc));
 
         ::RemovePropW(mPluginHWND, kPluginInstanceParentProperty);
 
         mPluginWndProc = nullptr;
@@ -1975,24 +1969,31 @@ PluginInstanceParent::SharedSurfaceAfter
 
 #endif // defined(OS_WIN)
 
 bool
 PluginInstanceParent::AnswerPluginFocusChange(const bool& gotFocus)
 {
     PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION));
 
-    // Currently only in use on windows - an rpc event we receive from the
-    // child when it's plugin window (or one of it's children) receives keyboard
-    // focus. We forward the event down to widget so the dom/focus manager can
-    // be updated.
+    // Currently only in use on windows - an event we receive from the child
+    // when it's plugin window (or one of it's children) receives keyboard
+    // focus. We detect this and forward a notification here so we can update
+    // focus.
 #if defined(OS_WIN)
-    // XXX This needs to go to PuppetWidget. bug ???
-    if (XRE_GetProcessType() == GeckoProcessType_Default) {
-      ::SendMessage(mPluginHWND, gOOPPPluginFocusEvent, gotFocus ? 1 : 0, 0);
+    if (gotFocus) {
+      nsPluginInstanceOwner* owner = GetOwner();
+      if (owner) {
+        nsIFocusManager* fm = nsFocusManager::GetFocusManager();
+        nsCOMPtr<nsIDOMElement> element;
+        owner->GetDOMElement(getter_AddRefs(element));
+        if (fm && element) {
+          fm->SetFocus(element, 0);
+        }
+      }
     }
     return true;
 #else
     NS_NOTREACHED("PluginInstanceParent::AnswerPluginFocusChange not implemented!");
     return false;
 #endif
 }
 
--- a/dom/push/PushService.jsm
+++ b/dom/push/PushService.jsm
@@ -814,16 +814,22 @@ this.PushService = {
       debug("Error creating valid URI from services.push.serverURL (" +
             serverURL + ")");
       return;
     }
 
     if (uri.scheme === "wss") {
       this._ws = Cc["@mozilla.org/network/protocol;1?name=wss"]
                    .createInstance(Ci.nsIWebSocketChannel);
+
+      this._ws.initLoadInfo(null, // aLoadingNode
+                            Services.scriptSecurityManager.getSystemPrincipal(),
+                            null, // aTriggeringPrincipal
+                            Ci.nsILoadInfo.SEC_NORMAL,
+                            Ci.nsIContentPolicy.TYPE_WEBSOCKET);
     }
     else if (uri.scheme === "ws") {
       debug("Push over an insecure connection (ws://) is not allowed!");
       return;
     }
     else {
       debug("Unsupported websocket scheme " + uri.scheme);
       return;
--- a/dom/webidl/PeerConnectionObserver.webidl
+++ b/dom/webidl/PeerConnectionObserver.webidl
@@ -18,16 +18,17 @@ interface PeerConnectionObserver
   void onCreateAnswerError(unsigned long name, DOMString message);
   void onSetLocalDescriptionSuccess();
   void onSetRemoteDescriptionSuccess();
   void onSetLocalDescriptionError(unsigned long name, DOMString message);
   void onSetRemoteDescriptionError(unsigned long name, DOMString message);
   void onAddIceCandidateSuccess();
   void onAddIceCandidateError(unsigned long name, DOMString message);
   void onIceCandidate(unsigned short level, DOMString mid, DOMString candidate);
+  void onNegotiationNeeded();
 
   /* Stats callbacks */
   void onGetStatsSuccess(optional RTCStatsReportInternal report);
   void onGetStatsError(unsigned long name, DOMString message);
 
   /* replaceTrack callbacks */
   void onReplaceTrackSuccess();
   void onReplaceTrackError(unsigned long name, DOMString message);
@@ -35,12 +36,12 @@ interface PeerConnectionObserver
   /* Data channel callbacks */
   void notifyDataChannel(DataChannel channel);
 
   /* Notification of one of several types of state changed */
   void onStateChange(PCObserverStateType state);
 
   /* Changes to MediaStreamTracks */
   void onAddStream(MediaStream stream);
-  void onRemoveStream();
+  void onRemoveStream(MediaStream stream);
   void onAddTrack(MediaStreamTrack track);
-  void onRemoveTrack();
+  void onRemoveTrack(MediaStreamTrack track);
 };
--- a/dom/workers/ServiceWorkerManager.cpp
+++ b/dom/workers/ServiceWorkerManager.cpp
@@ -125,17 +125,16 @@ ServiceWorkerRegistrationInfo::Clear()
     mInstallingWorker = nullptr;
     // FIXME(nsm): Abort any inflight requests from installing worker.
   }
 
   if (mWaitingWorker) {
     mWaitingWorker->UpdateState(ServiceWorkerState::Redundant);
     // Fire statechange.
     mWaitingWorker = nullptr;
-    mWaitingToActivate = false;
   }
 
   if (mActiveWorker) {
     mActiveWorker->UpdateState(ServiceWorkerState::Redundant);
     mActiveWorker = nullptr;
   }
 
   nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
@@ -194,33 +193,33 @@ ServiceWorkerManager::ServiceWorkerManag
 }
 
 ServiceWorkerManager::~ServiceWorkerManager()
 {
   // The map will assert if it is not empty when destroyed.
   mServiceWorkerRegistrationInfos.Clear();
 }
 
-class ServiceWorkerRegisterJob;
-
 class ContinueLifecycleTask : public nsISupports
 {
   NS_DECL_ISUPPORTS
 
 protected:
   virtual ~ContinueLifecycleTask()
   { }
 
 public:
   virtual void ContinueAfterWorkerEvent(bool aSuccess,
                                         bool aActivateImmediately) = 0;
 };
 
 NS_IMPL_ISUPPORTS0(ContinueLifecycleTask);
 
+class ServiceWorkerRegisterJob;
+
 class ContinueInstallTask MOZ_FINAL : public ContinueLifecycleTask
 {
   nsRefPtr<ServiceWorkerRegisterJob> mJob;
 
 public:
   explicit ContinueInstallTask(ServiceWorkerRegisterJob* aJob)
     : mJob(aJob)
   { }
@@ -233,20 +232,17 @@ class ContinueActivateTask MOZ_FINAL : p
   nsRefPtr<ServiceWorkerRegistrationInfo> mRegistration;
 
 public:
   explicit ContinueActivateTask(ServiceWorkerRegistrationInfo* aReg)
     : mRegistration(aReg)
   { }
 
   void
-  ContinueAfterWorkerEvent(bool aSuccess, bool aActivateImmediately /* unused */) MOZ_OVERRIDE
-  {
-    mRegistration->FinishActivate(aSuccess);
-  }
+  ContinueAfterWorkerEvent(bool aSuccess, bool aActivateImmediately /* unused */) MOZ_OVERRIDE;
 };
 
 class ContinueLifecycleRunnable MOZ_FINAL : public nsRunnable
 {
   nsMainThreadPtrHandle<ContinueLifecycleTask> mTask;
   bool mSuccess;
   bool mActivateImmediately;
 
@@ -566,30 +562,32 @@ public:
     swm->mSetOfScopesBeingUpdated.Put(mRegistration->mScope, true);
     nsRefPtr<ServiceWorker> serviceWorker;
     rv = swm->CreateServiceWorker(mRegistration->mPrincipal,
                                   mRegistration->mScriptSpec,
                                   mRegistration->mScope,
                                   getter_AddRefs(serviceWorker));
 
     if (NS_WARN_IF(NS_FAILED(rv))) {
+      swm->mSetOfScopesBeingUpdated.Remove(mRegistration->mScope);
       Fail(NS_ERROR_DOM_ABORT_ERR);
       return rv;
     }
 
     nsRefPtr<ServiceWorkerJob> upcasted = this;
     nsMainThreadPtrHandle<nsISupports> handle(
         new nsMainThreadPtrHolder<nsISupports>(upcasted));
 
     nsRefPtr<CheckWorkerEvaluationAndContinueUpdateWorkerRunnable> r =
       new CheckWorkerEvaluationAndContinueUpdateWorkerRunnable(serviceWorker->GetWorkerPrivate(), handle);
     AutoJSAPI jsapi;
     jsapi.Init();
     bool ok = r->Dispatch(jsapi.cx());
     if (NS_WARN_IF(!ok)) {
+      swm->mSetOfScopesBeingUpdated.Remove(mRegistration->mScope);
       Fail(NS_ERROR_DOM_ABORT_ERR);
       return rv;
     }
 
     return NS_OK;
   }
 
   // Public so our error handling code can use it.
@@ -603,54 +601,62 @@ public:
 
   // Public so our error handling code can continue with a successful worker.
   void
   ContinueInstall()
   {
     nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
     MOZ_ASSERT(swm->mSetOfScopesBeingUpdated.Contains(mRegistration->mScope));
     swm->mSetOfScopesBeingUpdated.Remove(mRegistration->mScope);
+    // This is effectively the end of Step 4.3 of the [[Update]] algorithm.
+    // The invocation of [[Install]] is not part of the atomic block.
+
+    // Begin [[Install]] atomic step 4.
     if (mRegistration->mInstallingWorker) {
       // FIXME(nsm): Terminate and stuff
       mRegistration->mInstallingWorker->UpdateState(ServiceWorkerState::Redundant);
     }
 
     swm->InvalidateServiceWorkerRegistrationWorker(mRegistration,
                                                    WhichServiceWorker::INSTALLING_WORKER);
     mRegistration->mInstallingWorker = new ServiceWorkerInfo(mRegistration, mRegistration->mScriptSpec);
     mRegistration->mInstallingWorker->UpdateState(ServiceWorkerState::Installing);
 
     Succeed();
 
+    // Step 4.6 "Queue a task..." for updatefound.
     nsCOMPtr<nsIRunnable> upr =
       NS_NewRunnableMethodWithArg<ServiceWorkerRegistrationInfo*>(swm,
                                                                   &ServiceWorkerManager::FireUpdateFound,
                                                                   mRegistration);
     NS_DispatchToMainThread(upr);
 
-    nsMainThreadPtrHandle<ContinueLifecycleTask> handle(
-        new nsMainThreadPtrHolder<ContinueLifecycleTask>(new ContinueInstallTask(this)));
-
     nsRefPtr<ServiceWorker> serviceWorker;
     nsresult rv =
       swm->CreateServiceWorker(mRegistration->mPrincipal,
                                mRegistration->mInstallingWorker->ScriptSpec(),
                                mRegistration->mScope,
                                getter_AddRefs(serviceWorker));
 
     if (NS_WARN_IF(NS_FAILED(rv))) {
-      ContinueAfterInstallEvent(false /* success */, false /* activate immediately */);
+      ContinueAfterInstallEvent(false /* aSuccess */, false /* aActivateImmediately */);
       return;
     }
 
+    nsMainThreadPtrHandle<ContinueLifecycleTask> handle(
+        new nsMainThreadPtrHolder<ContinueLifecycleTask>(new ContinueInstallTask(this)));
+
     nsRefPtr<LifecycleEventWorkerRunnable> r =
       new LifecycleEventWorkerRunnable(serviceWorker->GetWorkerPrivate(), NS_LITERAL_STRING("install"), handle);
 
     AutoJSAPI jsapi;
     jsapi.Init();
+
+    // This triggers Step 4.7 "Queue a task to run the following substeps..."
+    // which sends the install event to the worker.
     r->Dispatch(jsapi.cx());
   }
 
 private:
   void
   Update()
   {
     MOZ_ASSERT(mRegistration);
@@ -722,17 +728,18 @@ private:
     mCallback->UpdateSucceeded(mRegistration);
     mCallback = nullptr;
   }
 
   void
   FailCommon(nsresult aRv)
   {
     mCallback = nullptr;
-    MaybeRemoveRegistration();
+    nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
+    swm->MaybeRemoveRegistration(mRegistration);
     // Ensures that the job can't do anything useful from this point on.
     mRegistration = nullptr;
     Done(aRv);
   }
 
   // This MUST only be called when the job is still performing actions related
   // to registration or update. After the spec resolves the update promise, use
   // Done() with the failure code instead.
@@ -740,71 +747,56 @@ private:
   Fail(nsresult aRv)
   {
     MOZ_ASSERT(mCallback);
     mCallback->UpdateFailed(aRv);
     FailCommon(aRv);
   }
 
   void
-  MaybeRemoveRegistration()
+  ContinueAfterInstallEvent(bool aInstallEventSuccess, bool aActivateImmediately)
   {
-    MOZ_ASSERT(mRegistration);
-    nsRefPtr<ServiceWorkerInfo> newest = mRegistration->Newest();
-    if (!newest) {
-      nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
-      swm->RemoveRegistration(mRegistration);
-    }
-  }
-
-  void
-  ContinueAfterInstallEvent(bool aSuccess, bool aActivateImmediately)
-  {
-    // By this point the callback should've been notified about success or fail
-    // and nulled.
-    MOZ_ASSERT(!mCallback);
-
     if (!mRegistration->mInstallingWorker) {
       NS_WARNING("mInstallingWorker was null.");
       return Done(NS_ERROR_DOM_ABORT_ERR);
     }
 
     nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
 
     // "If installFailed is true"
-    if (!aSuccess) {
+    if (!aInstallEventSuccess) {
       mRegistration->mInstallingWorker->UpdateState(ServiceWorkerState::Redundant);
       mRegistration->mInstallingWorker = nullptr;
       swm->InvalidateServiceWorkerRegistrationWorker(mRegistration,
                                                      WhichServiceWorker::INSTALLING_WORKER);
-      MaybeRemoveRegistration();
+      swm->MaybeRemoveRegistration(mRegistration);
       return Done(NS_ERROR_DOM_ABORT_ERR);
     }
 
     // "If registration's waiting worker is not null"
     if (mRegistration->mWaitingWorker) {
       // FIXME(nsm): Terminate
       mRegistration->mWaitingWorker->UpdateState(ServiceWorkerState::Redundant);
     }
 
     // Although the spec first sets waiting worker and then updates its state,
     // our ServiceWorkerInfo does not hold a list of associated ServiceWorker
     // objects in content JS. This means if we want to fire an event on
     // ServiceWorkerRegistration.installing, we need to do it first, before
     // swapping it with waiting worker.
     mRegistration->mInstallingWorker->UpdateState(ServiceWorkerState::Installed);
     mRegistration->mWaitingWorker = mRegistration->mInstallingWorker.forget();
-    mRegistration->mWaitingToActivate = false;
     swm->InvalidateServiceWorkerRegistrationWorker(mRegistration,
                                                    WhichServiceWorker::INSTALLING_WORKER | WhichServiceWorker::WAITING_WORKER);
 
     // FIXME(nsm): Bug 982711 Deal with activateImmediately.
     NS_WARN_IF_FALSE(!aActivateImmediately, "Immediate activation using replace() is not supported yet");
+    Done(NS_OK);
+    // Activate() is invoked out of band of atomic.
     mRegistration->TryToActivate();
-    Done(NS_OK);
   }
 };
 
 NS_IMPL_ISUPPORTS_INHERITED(ServiceWorkerRegisterJob, ServiceWorkerJob, nsIStreamLoaderObserver);
 
 NS_IMETHODIMP
 ContinueUpdateRunnable::Run()
 {
@@ -813,16 +805,18 @@ ContinueUpdateRunnable::Run()
   nsRefPtr<ServiceWorkerRegisterJob> upjob = static_cast<ServiceWorkerRegisterJob*>(job.get());
   upjob->ContinueInstall();
   return NS_OK;
 }
 
 void
 ContinueInstallTask::ContinueAfterWorkerEvent(bool aSuccess, bool aActivateImmediately)
 {
+  // This does not start the job immediately if there are other jobs in the
+  // queue, which captures the "atomic" behaviour we want.
   mJob->ContinueAfterInstallEvent(aSuccess, aActivateImmediately);
 }
 
 // If we return an error code here, the ServiceWorkerContainer will
 // automatically reject the Promise.
 NS_IMETHODIMP
 ServiceWorkerManager::Register(nsIDOMWindow* aWindow,
                                const nsAString& aScope,
@@ -1095,28 +1089,30 @@ LifecycleEventWorkerRunnable::DispatchLi
     new LifecycleEventPromiseHandler(mTask, activateImmediately);
   waitUntilPromise->AppendNativeHandler(handler);
   return true;
 }
 
 void
 ServiceWorkerRegistrationInfo::TryToActivate()
 {
-  mWaitingToActivate = true;
   if (!IsControllingDocuments()) {
     Activate();
   }
 }
 
 void
+ContinueActivateTask::ContinueAfterWorkerEvent(bool aSuccess, bool aActivateImmediately /* unused */)
+{
+  mRegistration->FinishActivate(aSuccess);
+}
+
+void
 ServiceWorkerRegistrationInfo::Activate()
 {
-  MOZ_ASSERT(mWaitingToActivate);
-  mWaitingToActivate = false;
-
   nsRefPtr<ServiceWorkerInfo> activatingWorker = mWaitingWorker;
   nsRefPtr<ServiceWorkerInfo> exitingWorker = mActiveWorker;
 
   nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
   swm->InvalidateServiceWorkerRegistrationWorker(this, WhichServiceWorker::WAITING_WORKER | WhichServiceWorker::ACTIVE_WORKER);
   if (!activatingWorker) {
     NS_WARNING("No activatingWorker!");
     return;
@@ -1127,37 +1123,41 @@ ServiceWorkerRegistrationInfo::Activate(
     // Terminate worker
     exitingWorker->UpdateState(ServiceWorkerState::Redundant);
   }
 
   mActiveWorker = activatingWorker.forget();
   mWaitingWorker = nullptr;
   mActiveWorker->UpdateState(ServiceWorkerState::Activating);
 
+  // FIXME(nsm): Unlink appcache if there is one.
+
   swm->CheckPendingReadyPromises();
   swm->StoreRegistration(mPrincipal, this);
 
   // "Queue a task to fire a simple event named controllerchange..."
   nsCOMPtr<nsIRunnable> controllerChangeRunnable =
-    NS_NewRunnableMethodWithArg<ServiceWorkerRegistrationInfo*>(swm, &ServiceWorkerManager::FireControllerChange, this);
+    NS_NewRunnableMethodWithArg<ServiceWorkerRegistrationInfo*>(swm,
+                                                                &ServiceWorkerManager::FireControllerChange,
+                                                                this);
   NS_DispatchToMainThread(controllerChangeRunnable);
 
-  // XXXnsm I have my doubts about this. Leaving the main thread means that
-  // subsequent calls to Activate() not from a Register() call, i.e. due to all
-  // controlled documents going away, may lead to two or more calls being
-  // interleaved.
   MOZ_ASSERT(mActiveWorker);
   nsRefPtr<ServiceWorker> serviceWorker;
   nsresult rv =
     swm->CreateServiceWorker(mPrincipal,
                              mActiveWorker->ScriptSpec(),
                              mScope,
                              getter_AddRefs(serviceWorker));
   if (NS_WARN_IF(NS_FAILED(rv))) {
-    FinishActivate(false /* success */);
+    nsCOMPtr<nsIRunnable> r =
+      NS_NewRunnableMethodWithArg<bool>(this,
+                                        &ServiceWorkerRegistrationInfo::FinishActivate,
+                                        false /* success */);
+    MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(r)));
     return;
   }
 
   nsMainThreadPtrHandle<ContinueLifecycleTask> handle(
     new nsMainThreadPtrHolder<ContinueLifecycleTask>(new ContinueActivateTask(this)));
 
   nsRefPtr<LifecycleEventWorkerRunnable> r =
     new LifecycleEventWorkerRunnable(serviceWorker->GetWorkerPrivate(), NS_LITERAL_STRING("activate"), handle);
@@ -1683,17 +1683,20 @@ ServiceWorkerManager::HandleError(JSCont
 
   regJob->Fail(init);
   return true;
 }
 
 void
 ServiceWorkerRegistrationInfo::FinishActivate(bool aSuccess)
 {
-  MOZ_ASSERT(mActiveWorker);
+  if (mPendingUninstall || !mActiveWorker) {
+    return;
+  }
+
   if (aSuccess) {
     mActiveWorker->UpdateState(ServiceWorkerState::Activated);
   } else {
     mActiveWorker->UpdateState(ServiceWorkerState::Redundant);
     mActiveWorker = nullptr;
   }
 }
 
@@ -1928,46 +1931,46 @@ ServiceWorkerManager::RemoveScope(nsTArr
 {
   aList.RemoveElement(aScope);
 }
 
 void
 ServiceWorkerManager::MaybeStartControlling(nsIDocument* aDoc)
 {
   AssertIsOnMainThread();
-  if (!Preferences::GetBool("dom.serviceWorkers.enabled")) {
-    return;
-  }
-
   nsRefPtr<ServiceWorkerRegistrationInfo> registration =
     GetServiceWorkerRegistrationInfo(aDoc);
   if (registration) {
     MOZ_ASSERT(!mControlledDocuments.Contains(aDoc));
     registration->StartControllingADocument();
     // Use the already_AddRefed<> form of Put to avoid the addref-deref since
     // we don't need the registration pointer in this function anymore.
     mControlledDocuments.Put(aDoc, registration.forget());
   }
 }
 
 void
 ServiceWorkerManager::MaybeStopControlling(nsIDocument* aDoc)
 {
   MOZ_ASSERT(aDoc);
-  if (!Preferences::GetBool("dom.serviceWorkers.enabled")) {
-    return;
-  }
-
   nsRefPtr<ServiceWorkerRegistrationInfo> registration;
   mControlledDocuments.Remove(aDoc, getter_AddRefs(registration));
   // A document which was uncontrolled does not maintain that state itself, so
   // it will always call MaybeStopControlling() even if there isn't an
   // associated registration. So this check is required.
   if (registration) {
     registration->StopControllingADocument();
+    if (!registration->IsControllingDocuments()) {
+      if (registration->mPendingUninstall) {
+        registration->Clear();
+        RemoveRegistration(registration);
+      } else {
+        registration->TryToActivate();
+      }
+    }
   }
 }
 
 NS_IMETHODIMP
 ServiceWorkerManager::GetScopeForUrl(const nsAString& aUrl, nsAString& aScope)
 {
   nsCOMPtr<nsIURI> uri;
   nsresult rv = NS_NewURI(getter_AddRefs(uri), aUrl, nullptr, nullptr);
@@ -2405,9 +2408,19 @@ ServiceWorkerManager::CreateNewRegistrat
   ServiceWorkerRegistrationInfo* registration = new ServiceWorkerRegistrationInfo(aScope, aPrincipal);
   // From now on ownership of registration is with
   // mServiceWorkerRegistrationInfos.
   mServiceWorkerRegistrationInfos.Put(aScope, registration);
   AddScope(mOrderedScopes, aScope);
   return registration;
 }
 
+void
+ServiceWorkerManager::MaybeRemoveRegistration(ServiceWorkerRegistrationInfo* aRegistration)
+{
+  MOZ_ASSERT(aRegistration);
+  nsRefPtr<ServiceWorkerInfo> newest = aRegistration->Newest();
+  if (!newest) {
+    RemoveRegistration(aRegistration);
+  }
+}
+
 END_WORKERS_NAMESPACE
--- a/dom/workers/ServiceWorkerManager.h
+++ b/dom/workers/ServiceWorkerManager.h
@@ -44,16 +44,17 @@ namespace workers {
 
 class ServiceWorker;
 class ServiceWorkerInfo;
 
 class ServiceWorkerJobQueue;
 
 class ServiceWorkerJob : public nsISupports
 {
+protected:
   // The queue keeps the jobs alive, so they can hold a rawptr back to the
   // queue.
   ServiceWorkerJobQueue* mQueue;
 
 public:
   NS_DECL_ISUPPORTS
 
   virtual void Start() = 0;
@@ -146,17 +147,16 @@ public:
   nsRefPtr<ServiceWorkerInfo> mActiveWorker;
   nsRefPtr<ServiceWorkerInfo> mWaitingWorker;
   nsRefPtr<ServiceWorkerInfo> mInstallingWorker;
 
   // When unregister() is called on a registration, it is not immediately
   // removed since documents may be controlled. It is marked as
   // pendingUninstall and when all controlling documents go away, removed.
   bool mPendingUninstall;
-  bool mWaitingToActivate;
 
   explicit ServiceWorkerRegistrationInfo(const nsACString& aScope,
                                          nsIPrincipal* aPrincipal);
 
   already_AddRefed<ServiceWorkerInfo>
   Newest()
   {
     nsRefPtr<ServiceWorkerInfo> newest;
@@ -284,23 +284,21 @@ public:
  * The ServiceWorkerManager is a per-process global that deals with the
  * installation, querying and event dispatch of ServiceWorkers for all the
  * origins in the process.
  */
 class ServiceWorkerManager MOZ_FINAL
   : public nsIServiceWorkerManager
   , public nsIIPCBackgroundChildCreateCallback
 {
-  friend class ActivationRunnable;
-  friend class ServiceWorkerRegistrationInfo;
-  friend class ServiceWorkerRegisterJob;
   friend class GetReadyPromiseRunnable;
   friend class GetRegistrationsRunnable;
   friend class GetRegistrationRunnable;
-  friend class QueueFireUpdateFoundRunnable;
+  friend class ServiceWorkerRegisterJob;
+  friend class ServiceWorkerRegistrationInfo;
   friend class ServiceWorkerUnregisterJob;
 
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSISERVICEWORKERMANAGER
   NS_DECL_NSIIPCBACKGROUNDCHILDCREATECALLBACK
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_SERVICEWORKERMANAGER_IMPL_IID)
 
@@ -344,16 +342,18 @@ public:
   }
 
   ServiceWorkerRegistrationInfo*
   CreateNewRegistration(const nsCString& aScope, nsIPrincipal* aPrincipal);
 
   void
   RemoveRegistration(ServiceWorkerRegistrationInfo* aRegistration)
   {
+    MOZ_ASSERT(aRegistration);
+    MOZ_ASSERT(!aRegistration->IsControllingDocuments());
     MOZ_ASSERT(mServiceWorkerRegistrationInfos.Contains(aRegistration->mScope));
     ServiceWorkerManager::RemoveScope(mOrderedScopes, aRegistration->mScope);
     mServiceWorkerRegistrationInfos.Remove(aRegistration->mScope);
   }
 
   ServiceWorkerJobQueue*
   GetOrCreateJobQueue(const nsCString& aScope)
   {
@@ -486,16 +486,19 @@ private:
   }
 
   static PLDHashOperator
   CheckPendingReadyPromisesEnumerator(nsISupports* aSupports,
                                       nsAutoPtr<PendingReadyPromise>& aData,
                                       void* aUnused);
 
   nsClassHashtable<nsISupportsHashKey, PendingReadyPromise> mPendingReadyPromises;
+ 
+  void
+  MaybeRemoveRegistration(ServiceWorkerRegistrationInfo* aRegistration);
 
   mozilla::ipc::PBackgroundChild* mActor;
 
   struct PendingOperation;
   nsTArray<PendingOperation> mPendingOperations;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(ServiceWorkerManager,
--- a/dom/workers/test/serviceworkers/controller/index.html
+++ b/dom/workers/test/serviceworkers/controller/index.html
@@ -12,21 +12,21 @@
 <body>
 <p id="display"></p>
 <div id="content" style="display: none"></div>
 <pre id="test"></pre>
 <script class="testbody" type="text/javascript">
 
   // Make sure to use good, unique messages, since the actual expression will not show up in test results.
   function my_ok(result, msg) {
-    window.opener.postMessage({status: "ok", result: result, message: msg}, "*");
+    parent.postMessage({status: "ok", result: result, message: msg}, "*");
   }
 
   function finish() {
-    window.opener.postMessage({status: "done"}, "*");
+    parent.postMessage({status: "done"}, "*");
   }
 
   navigator.serviceWorker.ready.then(function(swr) {
     my_ok(swr.scope.match(/serviceworkers\/control$/),
           "This page should be controlled by upper level registration");
     my_ok(swr.installing == undefined,
           "Upper level registration should not have a installing worker.");
     if (navigator.serviceWorker.controller) {
--- a/dom/workers/test/serviceworkers/install_event_error_worker.js
+++ b/dom/workers/test/serviceworkers/install_event_error_worker.js
@@ -1,4 +1,4 @@
 // Worker that errors on receiving an install event.
 oninstall = function(e) {
   undefined.doSomething;
-}
+};
--- a/dom/workers/test/serviceworkers/mochitest.ini
+++ b/dom/workers/test/serviceworkers/mochitest.ini
@@ -1,10 +1,10 @@
 [DEFAULT]
-skip-if = buildapp == 'b2g' || android_version == "10" # bug 1056702
+skip-if = buildapp == 'b2g'
 support-files =
   worker.js
   worker2.js
   worker3.js
   parse_error_worker.js
   activate_event_error_worker.js
   install_event_worker.js
   install_event_error_worker.js
@@ -17,23 +17,21 @@ support-files =
   sw_clients/simple.html
   sw_clients/service_worker_controlled.html
   get_serviced_worker.js
   worker_unregister.js
   worker_update.js
   message_posting_worker.js
 
 [test_unregister.html]
-skip-if = true # bug 1094375
+skip-if = true # Bug 1133805
 [test_installation_simple.html]
-skip-if = true # bug 1094375
 [test_get_serviced.html]
 [test_install_event.html]
 [test_navigator.html]
 [test_scopes.html]
-skip-if = true # bug 1126470 and many others
 [test_controller.html]
 [test_workerUpdate.html]
-skip-if = true # Enable after Bug 982726 postMessage is landed.
+skip-if = true # Bug 1133805
 [test_workerUnregister.html]
-skip-if = true # Enable after Bug 982726 postMessage is landed.
+skip-if = true # Bug 1133805
 [test_post_message.html]
 [test_post_message_advanced.html]
--- a/dom/workers/test/serviceworkers/simpleregister/ready.html
+++ b/dom/workers/test/serviceworkers/simpleregister/ready.html
@@ -1,17 +1,15 @@
 <html>
   <head></head>
   <body>
     <script type="text/javascript">
 
-       window.addEventListener('message', function(evt) {
-         navigator.serviceWorker.ready.then(function() {
-           navigator.serviceWorker.oncontrollerchange = function(e) {
-             evt.ports[0].postMessage("WOW!");
-           }
-         });
-       }, false);
+      window.addEventListener('message', function(evt) {
+        navigator.serviceWorker.ready.then(function() {
+          evt.ports[0].postMessage("WOW!");
+        });
+      }, false);
 
     </script>
   </body>
 </html>
 
--- a/dom/workers/test/serviceworkers/test_controller.html
+++ b/dom/workers/test/serviceworkers/test_controller.html
@@ -10,39 +10,48 @@
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 <p id="display"></p>
 <div id="content" style="display: none"></div>
 <pre id="test"></pre>
 <script class="testbody" type="text/javascript">
 
+  var content;
+  var iframe;
+
   function simpleRegister() {
     // We use the control scope for the less specific registration. The window will register a worker on controller/
     return navigator.serviceWorker.register("worker.js", { scope: "./control" });
   }
 
   function testController() {
     var p = new Promise(function(resolve, reject) {
       window.onmessage = function(e) {
         if (e.data.status == "ok") {
           ok(e.data.result, e.data.message);
         } else if (e.data.status == "done") {
           window.onmessage = null;
-          w.close();
+          content.removeChild(iframe);
           resolve();
         }
       }
     });
 
-    var w = window.open("controller/index.html");
+    content = document.getElementById("content");
+    ok(content, "Parent exists.");
+
+    iframe = document.createElement("iframe");
+    iframe.setAttribute('src', "controller/index.html");
+    content.appendChild(iframe);
+
     return p;
   }
 
-  // This document just flips the prefs and opens the window for the actual test.
+  // This document just flips the prefs and opens the iframe for the actual test.
   function runTest() {
     simpleRegister()
       .then(testController)
       .then(function() {
         SimpleTest.finish();
       }).catch(function(e) {
         ok(false, "Some test failed with error " + e);
         SimpleTest.finish();
--- a/dom/workers/test/serviceworkers/test_install_event.html
+++ b/dom/workers/test/serviceworkers/test_install_event.html
@@ -33,19 +33,20 @@
       });
     }, function(e) {
       ok(false, "Unexpected Error in nextRegister! " + e);
     });
   }
 
   function installError() {
     // Silence worker errors so they don't cause the test to fail.
-    window.onerror = function() { }
+    window.onerror = function(e) {}
     return navigator.serviceWorker.register("install_event_error_worker.js", { scope: "./install_event" })
       .then(function(swr) {
+        ok(swr.installing instanceof ServiceWorker, "There should be an installing worker if promise resolves.");
         ok(swr.installing.state == "installing", "Installing worker's state should be 'installing'");
         return new Promise(function(resolve, reject) {
           swr.installing.onstatechange = function(e) {
             ok(e.target.state == "redundant", "Installation of worker with error should fail.");
             resolve();
           }
         });
       }).then(function() {
@@ -80,17 +81,18 @@
 
   function unregister() {
     return navigator.serviceWorker.getRegistration("./install_event").then(function(reg) {
       return reg.unregister();
     });
   }
 
   function runTest() {
-    simpleRegister()
+    Promise.resolve()
+      .then(simpleRegister)
       .then(nextRegister)
       .then(installError)
       .then(activateError)
       .then(unregister)
       .then(function() {
         SimpleTest.finish();
       }).catch(function(e) {
         ok(false, "Some test failed with error " + e);
--- a/dom/workers/test/serviceworkers/test_installation_simple.html
+++ b/dom/workers/test/serviceworkers/test_installation_simple.html
@@ -70,35 +70,16 @@
       ok(worker && wr.scope.match(/realworker$/) &&
          worker.scriptURL.match(/worker.js$/), "Valid worker instance should be available.");
     }, function(e) {
       info("Error: " + e.name);
       ok(false, "realWorker Registration should have succeeded!");
     });
   }
 
-  function abortPrevious() {
-    var p = navigator.serviceWorker.register("worker2.js", { scope: "foo/" });
-    var q = navigator.serviceWorker.register("worker3.js", { scope: "foo/" });
-
-    return Promise.all([
-      p.then(function(wr) {
-        ok(false, "First registration should fail with AbortError");
-      }, function(e) {
-        ok(e.name === "AbortError", "First registration should fail with AbortError");
-      }),
-
-      q.then(function(wr) {
-        ok(wr instanceof ServiceWorkerRegistration, "Second registration should succeed");
-      }, function(e) {
-        ok(false, "Second registration should succeed");
-      })
-    ]);
-  }
-
   function networkError404() {
     return navigator.serviceWorker.register("404.js", { scope: "network_error/"}).then(function(w) {
         ok(false, "Should fail with NetworkError");
       }, function(e) {
         ok(e.name === "NetworkError", "Should fail with NetworkError");
       });
   }
 
@@ -106,17 +87,16 @@
     var p = navigator.serviceWorker.register("parse_error_worker.js", { scope: "parse_error/" });
     return p.then(function(wr) {
       ok(false, "Registration should fail with parse error");
       return navigator.serviceWorker.getRegistration("parse_error/").then(function(swr) {
         // See https://github.com/slightlyoff/ServiceWorker/issues/547
         is(swr, undefined, "A failed registration for a scope with no prior controllers should clear itself");
       });
     }, function(e) {
-    info("NSM " + e.name);
       ok(e instanceof Error, "Registration should fail with parse error");
     });
   }
 
   // FIXME(nsm): test for parse error when Update step doesn't happen (directly from register).
 
   function updatefound() {
     var frame = document.createElement("iframe");
@@ -135,18 +115,17 @@
 
     window.onmessage = function(e) {
       if (e.data.type == "ready") {
         continueTest();
       } else if (e.data.type == "finish") {
         window.onmessage = null;
         // We have to make frame navigate away, otherwise it will call
         // MaybeStopControlling() when this document is unloaded. At that point
-        // the pref has been disabled, and so MaybeStopControlling() will just
-        // return since it is currently gated.
+        // the pref has been disabled, so the ServiceWorkerManager is not available.
         frame.setAttribute("src", new URL("about:blank").href);
         resolve();
       } else if (e.data.type == "check") {
         ok(e.data.status, e.data.msg);
       }
     }
     return p;
   }
@@ -178,17 +157,16 @@
 
   function runTest() {
     simpleRegister()
       .then(readyPromise)
       .then(sameOriginWorker)
       .then(sameOriginScope)
       .then(httpsOnly)
       .then(realWorker)
-      .then(abortPrevious)
       .then(networkError404)
       .then(parseError)
       .then(updatefound)
       .then(checkReadyPromise)
       // put more tests here.
       .then(function() {
         SimpleTest.finish();
       }).catch(function(e) {
--- a/dom/workers/test/serviceworkers/test_scopes.html
+++ b/dom/workers/test/serviceworkers/test_scopes.html
@@ -57,17 +57,17 @@
       ok(getScope(p("sua.html")) === p(""), "Scope should match");
       ok(getScope(p("sub.html")) === p("sub"), "Scope should match");
       ok(getScope(p("sub/dir.html")) === p("sub/dir.html"), "Scope should match");
       ok(getScope(p("sub/dir")) === p("sub/dir"), "Scope should match");
       ok(getScope(p("sub/dir/foo")) === p("sub/dir/"), "Scope should match");
       ok(getScope(p("sub/dir/afoo")) === p("sub/dir/a"), "Scope should match");
       ok(getScope(p("star*wars")) === p("star*"), "Scope should match");
       ok(getScope(p("star/a.html")) === p(""), "Scope should match");
-      resolve(true);
+      resolve();
     });
   }
 
   function runTest() {
     registerWorkers()
       .then(testScopes)
       .then(unregisterWorkers)
       .then(function() {
--- a/dom/workers/test/serviceworkers/unregister/index.html
+++ b/dom/workers/test/serviceworkers/unregister/index.html
@@ -14,31 +14,28 @@
 <div id="content" style="display: none"></div>
 <pre id="test"></pre>
 <script class="testbody" type="text/javascript">
 
   if (!parent) {
     info("unregister/index.html should not to be launched directly!");
   }
 
+  SimpleTest.requestFlakyTimeout("Unfortunately we have no way to test for a page being uncontrolled except waiting for ready to not resolve");
   var tId = setTimeout(function() {
-    info("tId timeout!");
     parent.postMessage({ controlled: false }, "*");
     tId = null;
   }, 2000);
 
   navigator.serviceWorker.ready.then(function() {
-  info("Got ready");
     if (tId == null) {
-    info("tId was null");
       parent.postMessage("FAIL!!!", "*");
       return;
     }
 
     clearTimeout(tId);
-    info("tId was non-null");
     parent.postMessage({ controlled: true }, "*");
   });
 
 </script>
 </pre>
 </body>
 </html>
--- a/dom/xul/templates/nsXULTemplateQueryProcessorStorage.cpp
+++ b/dom/xul/templates/nsXULTemplateQueryProcessorStorage.cpp
@@ -8,30 +8,30 @@
 #include "nsIDOMNodeList.h"
 #include "nsUnicharUtils.h"
 
 #include "nsArrayUtils.h"
 #include "nsIVariant.h"
 #include "nsAppDirectoryServiceDefs.h"
 
 #include "nsIURI.h"
-#include "nsIIOService.h"
 #include "nsIFileChannel.h"
 #include "nsIFile.h"
 #include "nsGkAtoms.h"
 #include "nsContentUtils.h"
 
 #include "nsXULTemplateBuilder.h"
 #include "nsXULTemplateResultStorage.h"
 #include "nsXULContentUtils.h"
 #include "nsXULSortService.h"
 
 #include "mozIStorageService.h"
 #include "nsIChannel.h"
 #include "nsIDocument.h"
+#include "nsNetUtil.h"
 
 //----------------------------------------------------------------------
 //
 // nsXULTemplateResultSetStorage
 //
 
 NS_IMPL_ISUPPORTS(nsXULTemplateResultSetStorage, nsISimpleEnumerator)
 
@@ -207,21 +207,23 @@ nsXULTemplateQueryProcessorStorage::GetD
                                              getter_AddRefs(databaseFile));
         NS_ENSURE_SUCCESS(rv, rv);
 
         rv = databaseFile->AppendNative(path);
         NS_ENSURE_SUCCESS(rv, rv);
     }
     else {
         nsCOMPtr<nsIChannel> channel;
-        nsCOMPtr<nsIIOService> ioservice =
-            do_GetService("@mozilla.org/network/io-service;1", &rv);
-        NS_ENSURE_SUCCESS(rv, rv);
+        nsCOMPtr<nsINode> node = do_QueryInterface(aRootNode);
 
-        rv = ioservice->NewChannelFromURI(uri, getter_AddRefs(channel));
+        rv = NS_NewChannel(getter_AddRefs(channel),
+                           uri,
+                           node,
+                           nsILoadInfo::SEC_NORMAL,
+                           nsIContentPolicy::TYPE_OTHER);
         NS_ENSURE_SUCCESS(rv, rv);
 
         nsCOMPtr<nsIFileChannel> fileChannel = do_QueryInterface(channel, &rv);
         if (NS_FAILED(rv)) { // if it fails, not a file url
             nsXULContentUtils::LogTemplateError(ERROR_TEMPLATE_STORAGE_BAD_URI);
             return rv;
         }
 
--- a/embedding/components/webbrowserpersist/nsWebBrowserPersist.cpp
+++ b/embedding/components/webbrowserpersist/nsWebBrowserPersist.cpp
@@ -3623,21 +3623,21 @@ nsWebBrowserPersist::SaveSubframeContent
 }
 
 nsresult
 nsWebBrowserPersist::CreateChannelFromURI(nsIURI *aURI, nsIChannel **aChannel)
 {
     nsresult rv = NS_OK;
     *aChannel = nullptr;
 
-    nsCOMPtr<nsIIOService> ioserv;
-    ioserv = do_GetIOService(&rv);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    rv = ioserv->NewChannelFromURI(aURI, aChannel);
+    rv = NS_NewChannel(aChannel,
+                       aURI,
+                       nsContentUtils::GetSystemPrincipal(),
+                       nsILoadInfo::SEC_NORMAL,
+                       nsIContentPolicy::TYPE_OTHER);
     NS_ENSURE_SUCCESS(rv, rv);
     NS_ENSURE_ARG_POINTER(*aChannel);
 
     rv = (*aChannel)->SetNotificationCallbacks(static_cast<nsIInterfaceRequestor*>(this));
     NS_ENSURE_SUCCESS(rv, rv);
     return NS_OK;
 }
 
--- a/extensions/cookie/nsPermissionManager.cpp
+++ b/extensions/cookie/nsPermissionManager.cpp
@@ -1890,28 +1890,26 @@ nsPermissionManager::Import()
 nsresult
 nsPermissionManager::ImportDefaults()
 {
   nsCString defaultsURL = mozilla::Preferences::GetCString(kDefaultsUrlPrefName);
   if (defaultsURL.IsEmpty()) { // == Don't use built-in permissions.
     return NS_OK;
   }
 
-  nsresult rv;
-  nsCOMPtr<nsIIOService> ioservice =
-    do_GetService("@mozilla.org/network/io-service;1", &rv);
-  NS_ENSURE_SUCCESS(rv, rv);
-
   nsCOMPtr<nsIURI> defaultsURI;
-  rv = NS_NewURI(getter_AddRefs(defaultsURI), defaultsURL,
-                 nullptr, nullptr, ioservice);
+  nsresult rv = NS_NewURI(getter_AddRefs(defaultsURI), defaultsURL);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIChannel> channel;
-  rv = ioservice->NewChannelFromURI(defaultsURI, getter_AddRefs(channel));
+  rv = NS_NewChannel(getter_AddRefs(channel),
+                     defaultsURI,
+                     nsContentUtils::GetSystemPrincipal(),
+                     nsILoadInfo::SEC_NORMAL,
+                     nsIContentPolicy::TYPE_OTHER);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIInputStream> inputStream;
   rv = channel->Open(getter_AddRefs(inputStream));
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = _DoImport(inputStream, nullptr);
   inputStream->Close();
--- a/extensions/pref/autoconfig/src/nsReadConfig.cpp
+++ b/extensions/pref/autoconfig/src/nsReadConfig.cpp
@@ -19,16 +19,17 @@
 #include "nsToolkitCompsCID.h"
 #include "nsXPIDLString.h"
 #include "nsNetUtil.h"
 #include "prmem.h"
 #include "nsString.h"
 #include "nsCRT.h"
 #include "nspr.h"
 #include "nsXULAppAPI.h"
+#include "nsContentUtils.h"
 
 extern PRLogModuleInfo *MCD;
 
 extern nsresult EvaluateAdminConfigScript(const char *js_buffer, size_t length,
                                           const char *filename, 
                                           bool bGlobalContext, 
                                           bool bCallbacks, 
                                           bool skipFirstLine);
@@ -248,36 +249,33 @@ nsresult nsReadConfig::openAndEvaluateJS
         if (NS_FAILED(rv)) 
             return rv;
 
         rv = NS_NewLocalFileInputStream(getter_AddRefs(inStr), jsFile);
         if (NS_FAILED(rv)) 
             return rv;
 
     } else {
-        nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
-        if (NS_FAILED(rv)) 
-            return rv;
-
         nsAutoCString location("resource://gre/defaults/autoconfig/");
         location += aFileName;
 
         nsCOMPtr<nsIURI> uri;
-        rv = ioService->NewURI(location, nullptr, nullptr, getter_AddRefs(uri));
-        if (NS_FAILED(rv))
-            return rv;
+        rv = NS_NewURI(getter_AddRefs(uri), location);
+        NS_ENSURE_SUCCESS(rv, rv);
 
         nsCOMPtr<nsIChannel> channel;
-        rv = ioService->NewChannelFromURI(uri, getter_AddRefs(channel));
-        if (NS_FAILED(rv))
-            return rv;
+        rv = NS_NewChannel(getter_AddRefs(channel),
+                           uri,
+                           nsContentUtils::GetSystemPrincipal(),
+                           nsILoadInfo::SEC_NORMAL,
+                           nsIContentPolicy::TYPE_OTHER);
+        NS_ENSURE_SUCCESS(rv, rv);
 
         rv = channel->Open(getter_AddRefs(inStr));
-        if (NS_FAILED(rv)) 
-            return rv;
+        NS_ENSURE_SUCCESS(rv, rv);
     }
 
     uint64_t fs64;
     uint32_t amt = 0;
     rv = inStr->Available(&fs64);
     if (NS_FAILED(rv))
         return rv;
     // PR_Malloc dones't support over 4GB
--- a/gfx/layers/client/ClientTiledPaintedLayer.cpp
+++ b/gfx/layers/client/ClientTiledPaintedLayer.cpp
@@ -413,46 +413,30 @@ ClientTiledPaintedLayer::RenderLayer()
   }
 
   if (!ClientManager()->IsRepeatTransaction()) {
     // Only paint the mask layer on the first transaction.
     if (GetMaskLayer()) {
       ToClientLayer(GetMaskLayer())->RenderLayer();
     }
 
-    // For more complex cases we need to calculate a bunch of metrics before we
-    // can do the paint.
-    BeginPaint();
-    if (mPaintData.mPaintFinished) {
-      return;
-    }
-
     // In some cases we can take a fast path and just be done with it.
     if (UseFastPath()) {
       TILING_LOG("TILING %p: Taking fast-path\n", this);
       mValidRegion = neededRegion;
-
-      // Make sure that tiles that fall outside of the visible region or outside of the
-      // critical displayport are discarded on the first update. Also make sure that we
-      // only draw stuff inside the critical displayport on the first update.
-      if (!mPaintData.mCriticalDisplayPort.IsEmpty()) {
-        mValidRegion.And(mValidRegion, LayerIntRect::ToUntyped(mPaintData.mCriticalDisplayPort));
-        invalidRegion.And(invalidRegion, LayerIntRect::ToUntyped(mPaintData.mCriticalDisplayPort));
-      }
-
-      if (invalidRegion.IsEmpty()) {
-        EndPaint();
-        return;
-      }
-
-      mContentClient->mTiledBuffer.SetFrameResolution(mPaintData.mResolution);
       mContentClient->mTiledBuffer.PaintThebes(mValidRegion, invalidRegion, callback, data);
       ClientManager()->Hold(this);
       mContentClient->UseTiledLayerBuffer(TiledContentClient::TILED_BUFFER);
-      EndPaint();
+      return;
+    }
+
+    // For more complex cases we need to calculate a bunch of metrics before we
+    // can do the paint.
+    BeginPaint();
+    if (mPaintData.mPaintFinished) {
       return;
     }
 
     // Make sure that tiles that fall outside of the visible region or outside of the
     // critical displayport are discarded on the first update. Also make sure that we
     // only draw stuff inside the critical displayport on the first update.
     mValidRegion.And(mValidRegion, neededRegion);
     if (!mPaintData.mCriticalDisplayPort.IsEmpty()) {
--- a/js/src/asmjs/AsmJSValidate.cpp
+++ b/js/src/asmjs/AsmJSValidate.cpp
@@ -2132,23 +2132,18 @@ IsCoercionCall(ModuleCompiler &m, ParseN
     if (coercedExpr)
         *coercedExpr = CallArgList(pn);
 
     if (global->isMathFunction() && global->mathBuiltinFunction() == AsmJSMathBuiltin_fround) {
         *coercion = AsmJS_FRound;
         return true;
     }
 
-    if (global->isSimdCtor() ||
-        (global->isSimdOperation() && global->simdOperation() == AsmJSSimdOperation_check))
-    {
-        AsmJSSimdType type = global->isSimdCtor()
-                             ? global->simdCtorType()
-                             : global->simdOperationType();
-        switch (type) {
+    if (global->isSimdOperation() && global->simdOperation() == AsmJSSimdOperation_check) {
+        switch (global->simdOperationType()) {
           case AsmJSSimdType_int32x4:
             *coercion = AsmJS_ToInt32x4;
             return true;
           case AsmJSSimdType_float32x4:
             *coercion = AsmJS_ToFloat32x4;
             return true;
         }
     }
@@ -5567,22 +5562,17 @@ class CheckSimdVectorScalarArgs
             if (!(actualType <= Type(formalSimdType_))) {
                 return f.failf(arg, "%s is not a subtype of %s", actualType.toChars(),
                                Type(formalSimdType_).toChars());
             }
             return true;
         }
 
         // Second argument is the scalar
-        Type coercedFormalType = SimdToCoercedScalarType(formalSimdType_);
-        if (!(actualType <= coercedFormalType)) {
-            return f.failf(arg, "%s is not a subtype of %s", actualType.toChars(),
-                           coercedFormalType.toChars());
-        }
-        return true;
+        return CheckSimdScalarArgs(formalSimdType_)(f, arg, argIndex, actualType, def);
     }
 };
 
 } // anonymous namespace
 
 static inline bool
 CheckSimdUnary(FunctionCompiler &f, ParseNode *call, AsmJSSimdType opType,
                MSimdUnaryArith::Operation op, MDefinition **def, Type *type)
@@ -5976,21 +5966,16 @@ CheckSimdOperationCall(FunctionCompiler 
 }
 
 static bool
 CheckSimdCtorCall(FunctionCompiler &f, ParseNode *call, const ModuleCompiler::Global *global,
                   MDefinition **def, Type *type)
 {
     MOZ_ASSERT(call->isKind(PNK_CALL));
 
-    AsmJSCoercion coercion;
-    ParseNode *argNode;
-    if (IsCoercionCall(f.m(), call, &coercion, &argNode))
-        return CheckCoercionArg(f, argNode, coercion, def, type);
-
     AsmJSSimdType simdType = global->simdCtorType();
     unsigned length = SimdTypeToLength(simdType);
     DefinitionVector defs;
     if (!CheckSimdCallArgs(f, call, length, CheckSimdScalarArgs(simdType), &defs))
         return false;
 
     // This code will need to be generalized when we handle float64x2
     MOZ_ASSERT(length == 4);
--- a/js/src/builtin/SIMD.cpp
+++ b/js/src/builtin/SIMD.cpp
@@ -345,27 +345,16 @@ SimdTypeToMinimumLanesNumber(SimdTypeDes
 }
 
 bool
 SimdTypeDescr::call(JSContext *cx, unsigned argc, Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
 
     Rooted<SimdTypeDescr*> descr(cx, &args.callee().as<SimdTypeDescr>());
-    if (args.length() == 1) {
-        // SIMD type used as a coercion
-        if (!CheckVectorObject(args[0], descr->type())) {
-            JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_SIMD_NOT_A_VECTOR);
-            return false;
-        }
-
-        args.rval().setObject(args[0].toObject());
-        return true;
-    }
-
     MOZ_ASSERT(size_t(static_cast<TypeDescr*>(descr)->size()) <= InlineTypedObject::MaximumSize,
                "inline storage is needed for using InternalHandle belows");
 
     Rooted<TypedObject*> result(cx, TypedObject::createZeroed(cx, descr, 0));
     if (!result)
         return false;
 
     switch (descr->type()) {
@@ -728,37 +717,28 @@ BinaryFunc(JSContext *cx, unsigned argc,
 
 template<typename V, template<typename T> class OpWith>
 static bool
 FuncWith(JSContext *cx, unsigned argc, Value *vp)
 {
     typedef typename V::Elem Elem;
 
     CallArgs args = CallArgsFromVp(argc, vp);
-    if (args.length() != 2 || !IsVectorObject<V>(args[0]) ||
-        (!args[1].isNumber() && !args[1].isBoolean()))
-    {
+    if (args.length() != 2 || !IsVectorObject<V>(args[0]))
         return ErrorBadArgs(cx);
-    }
 
-    Elem *val = TypedObjectMemory<Elem *>(args[0]);
+    Elem *vec = TypedObjectMemory<Elem *>(args[0]);
     Elem result[V::lanes];
 
-    if (args[1].isNumber()) {
-        Elem withAsNumber;
-        if (!V::toType(cx, args[1], &withAsNumber))
-            return false;
-        for (unsigned i = 0; i < V::lanes; i++)
-            result[i] = OpWith<Elem>::apply(i, withAsNumber, val[i]);
-    } else {
-        MOZ_ASSERT(args[1].isBoolean());
-        bool withAsBool = args[1].toBoolean();
-        for (unsigned i = 0; i < V::lanes; i++)
-            result[i] = OpWith<Elem>::apply(i, withAsBool, val[i]);
-    }
+    Elem value;
+    if (!V::toType(cx, args[1], &value))
+        return false;
+
+    for (unsigned i = 0; i < V::lanes; i++)
+        result[i] = OpWith<Elem>::apply(i, 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;
@@ -822,17 +802,17 @@ template<typename Op>
 static bool
 Int32x4BinaryScalar(JSContext *cx, unsigned argc, Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     if (args.length() != 2)
         return ErrorBadArgs(cx);
 
     int32_t result[4];
-    if (!IsVectorObject<Int32x4>(args[0]) || !args[1].isNumber())
+    if (!IsVectorObject<Int32x4>(args[0]))
         return ErrorBadArgs(cx);
 
     int32_t *val = TypedObjectMemory<int32_t *>(args[0]);
     int32_t bits;
     if (!ToInt32(cx, args[1], &bits))
         return false;
 
     for (unsigned i = 0; i < 4; i++)
@@ -917,17 +897,17 @@ FuncZero(JSContext *cx, unsigned argc, V
 
 template<typename Vret>
 static bool
 FuncSplat(JSContext *cx, unsigned argc, Value *vp)
 {
     typedef typename Vret::Elem RetElem;
 
     CallArgs args = CallArgsFromVp(argc, vp);
-    if (args.length() != 1 || !args[0].isNumber())
+    if (args.length() != 1)
         return ErrorBadArgs(cx);
 
     RetElem arg;
     if (!Vret::toType(cx, args[0], &arg))
         return false;
 
     RetElem result[Vret::lanes];
     for (unsigned i = 0; i < Vret::lanes; i++)
--- a/js/src/builtin/SIMD.h
+++ b/js/src/builtin/SIMD.h
@@ -268,17 +268,20 @@ struct Float32x4 {
 
     static TypeDescr &GetTypeDescr(GlobalObject &global) {
         return global.float32x4TypeDescr().as<TypeDescr>();
     }
     static Elem toType(Elem a) {
         return a;
     }
     static bool toType(JSContext *cx, JS::HandleValue v, Elem *out) {
-        *out = v.toNumber();
+        double d;
+        if (!ToNumber(cx, v, &d))
+            return false;
+        *out = float(d);
         return true;
     }
     static void setReturn(CallArgs &args, Elem value) {
         args.rval().setDouble(JS::CanonicalizeNaN(value));
     }
 };
 
 struct Float64x2 {
@@ -288,18 +291,17 @@ struct Float64x2 {
 
     static TypeDescr &GetTypeDescr(GlobalObject &global) {
         return global.float64x2TypeDescr().as<TypeDescr>();
     }
     static Elem toType(Elem a) {
         return a;
     }
     static bool toType(JSContext *cx, JS::HandleValue v, Elem *out) {
-        *out = v.toNumber();
-        return true;
+        return ToNumber(cx, v, out);
     }
     static void setReturn(CallArgs &args, Elem value) {
         args.rval().setDouble(JS::CanonicalizeNaN(value));
     }
 };
 
 struct Int32x4 {
     typedef int32_t Elem;
--- a/js/src/jit-test/tests/asm.js/simd-mandelbrot.js
+++ b/js/src/jit-test/tests/asm.js/simd-mandelbrot.js
@@ -1,1815 +1,1816 @@
 // |jit-test| test-also-noasmjs
-/* -*- Mode: javascript; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 ; js-indent-level : 2 ; js-curly-indent-offset: 0 -*- */
-/* vim: set ts=2 et sw=2 tw=80: */
-
-// Mandelbrot using SIMD
-// Author: Peter Jensen, Intel Corporation
-
-load(libdir + "asm.js");
-if (!isSimdAvailable() || typeof SIMD === 'undefined') {
-    print("won't run tests as simd extensions aren't activated yet");
-    quit(0);
-}
-
-// global variables
-const MAX_ITERATIONS = 10;
-const DRAW_ITERATIONS = 10;
-
-const CANVAS_WIDTH = 20;
-const CANVAS_HEIGHT = 20;
-
-const LIMIT_SHOW = 20 * 20 * 4;
-
-// Asm.js module buffer.
-var buffer = new ArrayBuffer(16 * 1024 * 1024);
-var view = new Uint8Array(buffer);
-
-var moduleCode = `
-  "use asm"
-  var b8 = new global.Uint8Array(buffer);
-  var toF = global.Math.fround;
-  var i4 = global.SIMD.int32x4;
-  var f4 = global.SIMD.float32x4;
-  var i4add = i4.add;
-  var i4and = i4.and;
-  var f4add = f4.add;
-  var f4sub = f4.sub;
-  var f4mul = f4.mul;
-  var f4lessThanOrEqual = f4.lessThanOrEqual;
-  var f4splat = f4.splat;
-  var imul = global.Math.imul;
-  const one4 = i4(1,1,1,1), two4 = f4(2,2,2,2), four4 = f4(4,4,4,4);
-
-  const mk0 = 0x007fffff;
-
-  function declareHeapLength() {
-    b8[0x00ffffff] = 0;
-  }
-
-  function mapColorAndSetPixel (x, y, width, value, max_iterations) {
-    x = x | 0;
-    y = y | 0;
-    width = width | 0;
-    value = value | 0;
-    max_iterations = max_iterations | 0;
-
-    var rgb = 0, r = 0, g = 0, b = 0, index = 0;
-
-    index = (((imul((width >>> 0), (y >>> 0)) + x) | 0) * 4) | 0;
-    if ((value | 0) == (max_iterations | 0)) {
-      r = 0;
-      g = 0;
-      b = 0;
-    } else {
-      rgb = ~~toF(toF(toF(toF(value >>> 0) * toF(0xffff)) / toF(max_iterations >>> 0)) * toF(0xff));
-      r = rgb & 0xff;
-      g = (rgb >>> 8) & 0xff;
-      b = (rgb >>> 16) & 0xff;
-    }
-    b8[(index & mk0) >> 0] = r;
-    b8[(index & mk0) + 1 >> 0] = g;
-    b8[(index & mk0) + 2 >> 0] = b;
-    b8[(index & mk0) + 3 >> 0] = 255;
-  }
-
-  function mandelPixelX4 (xf, yf, yd, max_iterations) {
-    xf = toF(xf);
-    yf = toF(yf);
-    yd = toF(yd);
-    max_iterations = max_iterations | 0;
-    var c_re4  = f4(0,0,0,0), c_im4  = f4(0,0,0,0);
-    var z_re4  = f4(0,0,0,0), z_im4  = f4(0,0,0,0);
-    var count4 = i4(0,0,0,0);
-    var z_re24 = f4(0,0,0,0), z_im24 = f4(0,0,0,0);
-    var new_re4 = f4(0,0,0,0), new_im4 = f4(0,0,0,0);
-    var i = 0;
-    var mi4 = i4(0,0,0,0);
-
-    c_re4 = f4splat(xf);
-    c_im4 = f4(yf, toF(yd + yf), toF(yd + toF(yd + yf)), toF(yd + toF(yd + toF(yd + yf))));
-
-    z_re4  = c_re4;
-    z_im4  = c_im4;
-
-    for (i = 0; (i | 0) < (max_iterations | 0); i = (i + 1) | 0) {
-      z_re24 = f4mul(z_re4, z_re4);
-      z_im24 = f4mul(z_im4, z_im4);
-      mi4 = f4lessThanOrEqual(f4add(z_re24, z_im24), four4);
-      // If all 4 values are greater than 4.0, there's no reason to continue.
-      if ((mi4.signMask | 0) == 0x00)
-        break;
-
-      new_re4 = f4sub(z_re24, z_im24);
-      new_im4 = f4mul(f4mul(two4, z_re4), z_im4);
-      z_re4   = f4add(c_re4, new_re4);
-      z_im4   = f4add(c_im4, new_im4);
-      count4  = i4add(count4, i4and(mi4, one4));
-    }
-    return i4(count4);
-  }
-
-  function mandelColumnX4 (x, width, height, xf, yf, yd, max_iterations) {
-    x = x | 0;
-    width = width | 0;
-    height = height | 0;
-    xf = toF(xf);
-    yf = toF(yf);
-    yd = toF(yd);
-    max_iterations = max_iterations | 0;
-
-    var y = 0;
-    var ydx4 = toF(0);
-    var m4 = i4(0,0,0,0);
-
-    ydx4 = toF(yd * toF(4));
-    for (y = 0; (y | 0) < (height | 0); y = (y + 4) | 0) {
-      m4   = i4(mandelPixelX4(toF(xf), toF(yf), toF(yd), max_iterations));
-      mapColorAndSetPixel(x | 0, y | 0,   width, m4.x, max_iterations);
-      mapColorAndSetPixel(x | 0, (y + 1) | 0, width, m4.y, max_iterations);
-      mapColorAndSetPixel(x | 0, (y + 2) | 0, width, m4.z, max_iterations);
-      mapColorAndSetPixel(x | 0, (y + 3) | 0, width, m4.w, max_iterations);
-      yf = toF(yf + ydx4);
-    }
-  }
-
-  function mandel (width, height, xc, yc, scale, max_iterations) {
-    width = width | 0;
-    height = height | 0;
-    xc = toF(xc);
-    yc = toF(yc);
-    scale = toF(scale);
-    max_iterations = max_iterations | 0;
-
-    var x0 = toF(0), y0 = toF(0);
-    var xd = toF(0), yd = toF(0);
-    var xf = toF(0);
-    var x = 0;
-
-    x0 = toF(xc - toF(scale * toF(1.5)));
-    y0 = toF(yc - scale);
-    xd = toF(toF(scale * toF(3)) / toF(width >>> 0));
-    yd = toF(toF(scale * toF(2)) / toF(height >>> 0));
-    xf = x0;
-
-    for (x = 0; (x | 0) < (width | 0); x = (x + 1) | 0) {
-      mandelColumnX4(x, width, height, xf, y0, yd, max_iterations);
-      xf = toF(xf + xd);
-    }
-  }
-
-  return mandel;
-`;
-
-var FFI = {};
-var mandelbro = asmLink(asmCompile('global', 'ffi', 'buffer', moduleCode), this, FFI, buffer);
-
-function animateMandelbrot () {
-  var scale_start = 1.0;
-  var scale_end   = 0.0005;
-  var xc_start    = -0.5;
-  var yc_start    = 0.0;
-  var xc_end      = 0.0;
-  var yc_end      = 0.75;
-  var steps       = 200.0;
-  var scale_step  = (scale_end - scale_start)/steps;
-  var xc_step     = (xc_end - xc_start)/steps;
-  var yc_step     = (yc_end - yc_start)/steps;
-  var scale       = scale_start;
-  var xc          = xc_start;
-  var yc          = yc_start;
-  var i           = 0;
-  var now         = dateNow();
-
-  function draw1 () {
-    mandelbro(CANVAS_WIDTH, CANVAS_HEIGHT, xc, yc, scale, MAX_ITERATIONS);
-    if (scale < scale_end || scale > scale_start) {
-      scale_step = -scale_step;
-      xc_step = -xc_step;
-      yc_step = -yc_step;
-    }
-    scale += scale_step;
-    xc += xc_step;
-    yc += yc_step;
-    i++;
-  }
-
-  var b = dateNow();
-  for (var j = DRAW_ITERATIONS; j --> 0;)
-    draw1();
-  print(dateNow() - b);
-}
-
-animateMandelbrot();
-
-assertEq(view[0], 0, "0th value should be 0");
-assertEq(view[1], 0, "1th value should be 0");
-assertEq(view[2], 0, "2th value should be 0");
-assertEq(view[3], 255, "3th value should be 255");
-assertEq(view[4], 230, "4th value should be 230");
-assertEq(view[5], 127, "5th value should be 127");
-assertEq(view[6], 25, "6th value should be 25");
-assertEq(view[7], 255, "7th value should be 255");
-assertEq(view[8], 230, "8th value should be 230");
-assertEq(view[9], 127, "9th value should be 127");
-assertEq(view[10], 25, "10th value should be 25");
-assertEq(view[11], 255, "11th value should be 255");
-assertEq(view[12], 205, "12th value should be 205");
-assertEq(view[13], 255, "13th value should be 255");
-assertEq(view[14], 50, "14th value should be 50");
-assertEq(view[15], 255, "15th value should be 255");
-assertEq(view[16], 205, "16th value should be 205");
-assertEq(view[17], 255, "17th value should be 255");
-assertEq(view[18], 50, "18th value should be 50");
-assertEq(view[19], 255, "19th value should be 255");
-assertEq(view[20], 205, "20th value should be 205");
-assertEq(view[21], 255, "21th value should be 255");
-assertEq(view[22], 50, "22th value should be 50");
-assertEq(view[23], 255, "23th value should be 255");
-assertEq(view[24], 205, "24th value should be 205");
-assertEq(view[25], 255, "25th value should be 255");
-assertEq(view[26], 50, "26th value should be 50");
-assertEq(view[27], 255, "27th value should be 255");
-assertEq(view[28], 205, "28th value should be 205");
-assertEq(view[29], 255, "29th value should be 255");
-assertEq(view[30], 50, "30th value should be 50");
-assertEq(view[31], 255, "31th value should be 255");
-assertEq(view[32], 179, "32th value should be 179");
-assertEq(view[33], 127, "33th value should be 127");
-assertEq(view[34], 76, "34th value should be 76");
-assertEq(view[35], 255, "35th value should be 255");
-assertEq(view[36], 179, "36th value should be 179");
-assertEq(view[37], 127, "37th value should be 127");
-assertEq(view[38], 76, "38th value should be 76");
-assertEq(view[39], 255, "39th value should be 255");
-assertEq(view[40], 179, "40th value should be 179");
-assertEq(view[41], 127, "41th value should be 127");
-assertEq(view[42], 76, "42th value should be 76");
-assertEq(view[43], 255, "43th value should be 255");
-assertEq(view[44], 154, "44th value should be 154");
-assertEq(view[45], 255, "45th value should be 255");
-assertEq(view[46], 101, "46th value should be 101");
-assertEq(view[47], 255, "47th value should be 255");
-assertEq(view[48], 78, "48th value should be 78");
-assertEq(view[49], 127, "49th value should be 127");
-assertEq(view[50], 178, "50th value should be 178");
-assertEq(view[51], 255, "51th value should be 255");
-assertEq(view[52], 52, "52th value should be 52");
-assertEq(view[53], 255, "53th value should be 255");
-assertEq(view[54], 203, "54th value should be 203");
-assertEq(view[55], 255, "55th value should be 255");
-assertEq(view[56], 154, "56th value should be 154");
-assertEq(view[57], 255, "57th value should be 255");
-assertEq(view[58], 101, "58th value should be 101");
-assertEq(view[59], 255, "59th value should be 255");
-assertEq(view[60], 179, "60th value should be 179");
-assertEq(view[61], 127, "61th value should be 127");
-assertEq(view[62], 76, "62th value should be 76");
-assertEq(view[63], 255, "63th value should be 255");
-assertEq(view[64], 205, "64th value should be 205");
-assertEq(view[65], 255, "65th value should be 255");
-assertEq(view[66], 50, "66th value should be 50");
-assertEq(view[67], 255, "67th value should be 255");
-assertEq(view[68], 205, "68th value should be 205");
-assertEq(view[69], 255, "69th value should be 255");
-assertEq(view[70], 50, "70th value should be 50");
-assertEq(view[71], 255, "71th value should be 255");
-assertEq(view[72], 230, "72th value should be 230");
-assertEq(view[73], 127, "73th value should be 127");
-assertEq(view[74], 25, "74th value should be 25");
-assertEq(view[75], 255, "75th value should be 255");
-assertEq(view[76], 230, "76th value should be 230");
-assertEq(view[77], 127, "77th value should be 127");
-assertEq(view[78], 25, "78th value should be 25");
-assertEq(view[79], 255, "79th value should be 255");
-assertEq(view[80], 0, "80th value should be 0");
-assertEq(view[81], 0, "81th value should be 0");
-assertEq(view[82], 0, "82th value should be 0");
-assertEq(view[83], 255, "83th value should be 255");
-assertEq(view[84], 230, "84th value should be 230");
-assertEq(view[85], 127, "85th value should be 127");
-assertEq(view[86], 25, "86th value should be 25");
-assertEq(view[87], 255, "87th value should be 255");
-assertEq(view[88], 205, "88th value should be 205");
-assertEq(view[89], 255, "89th value should be 255");
-assertEq(view[90], 50, "90th value should be 50");
-assertEq(view[91], 255, "91th value should be 255");
-assertEq(view[92], 205, "92th value should be 205");
-assertEq(view[93], 255, "93th value should be 255");
-assertEq(view[94], 50, "94th value should be 50");
-assertEq(view[95], 255, "95th value should be 255");
-assertEq(view[96], 205, "96th value should be 205");
-assertEq(view[97], 255, "97th value should be 255");
-assertEq(view[98], 50, "98th value should be 50");
-assertEq(view[99], 255, "99th value should be 255");
-assertEq(view[100], 205, "100th value should be 205");
-assertEq(view[101], 255, "101th value should be 255");
-assertEq(view[102], 50, "102th value should be 50");
-assertEq(view[103], 255, "103th value should be 255");
-assertEq(view[104], 205, "104th value should be 205");
-assertEq(view[105], 255, "105th value should be 255");
-assertEq(view[106], 50, "106th value should be 50");
-assertEq(view[107], 255, "107th value should be 255");
-assertEq(view[108], 205, "108th value should be 205");
-assertEq(view[109], 255, "109th value should be 255");
-assertEq(view[110], 50, "110th value should be 50");
-assertEq(view[111], 255, "111th value should be 255");
-assertEq(view[112], 179, "112th value should be 179");
-assertEq(view[113], 127, "113th value should be 127");
-assertEq(view[114], 76, "114th value should be 76");
-assertEq(view[115], 255, "115th value should be 255");
-assertEq(view[116], 179, "116th value should be 179");
-assertEq(view[117], 127, "117th value should be 127");
-assertEq(view[118], 76, "118th value should be 76");
-assertEq(view[119], 255, "119th value should be 255");
-assertEq(view[120], 154, "120th value should be 154");
-assertEq(view[121], 255, "121th value should be 255");
-assertEq(view[122], 101, "122th value should be 101");
-assertEq(view[123], 255, "123th value should be 255");
-assertEq(view[124], 103, "124th value should be 103");
-assertEq(view[125], 255, "125th value should be 255");
-assertEq(view[126], 152, "126th value should be 152");
-assertEq(view[127], 255, "127th value should be 255");
-assertEq(view[128], 0, "128th value should be 0");
-assertEq(view[129], 0, "129th value should be 0");
-assertEq(view[130], 0, "130th value should be 0");
-assertEq(view[131], 255, "131th value should be 255");
-assertEq(view[132], 0, "132th value should be 0");
-assertEq(view[133], 0, "133th value should be 0");
-assertEq(view[134], 0, "134th value should be 0");
-assertEq(view[135], 255, "135th value should be 255");
-assertEq(view[136], 128, "136th value should be 128");
-assertEq(view[137], 127, "137th value should be 127");
-assertEq(view[138], 127, "138th value should be 127");
-assertEq(view[139], 255, "139th value should be 255");
-assertEq(view[140], 154, "140th value should be 154");
-assertEq(view[141], 255, "141th value should be 255");
-assertEq(view[142], 101, "142th value should be 101");
-assertEq(view[143], 255, "143th value should be 255");
-assertEq(view[144], 179, "144th value should be 179");
-assertEq(view[145], 127, "145th value should be 127");
-assertEq(view[146], 76, "146th value should be 76");
-assertEq(view[147], 255, "147th value should be 255");
-assertEq(view[148], 205, "148th value should be 205");
-assertEq(view[149], 255, "149th value should be 255");
-assertEq(view[150], 50, "150th value should be 50");
-assertEq(view[151], 255, "151th value should be 255");
-assertEq(view[152], 205, "152th value should be 205");
-assertEq(view[153], 255, "153th value should be 255");
-assertEq(view[154], 50, "154th value should be 50");
-assertEq(view[155], 255, "155th value should be 255");
-assertEq(view[156], 230, "156th value should be 230");
-assertEq(view[157], 127, "157th value should be 127");
-assertEq(view[158], 25, "158th value should be 25");
-assertEq(view[159], 255, "159th value should be 255");
-assertEq(view[160], 0, "160th value should be 0");
-assertEq(view[161], 0, "161th value should be 0");
-assertEq(view[162], 0, "162th value should be 0");
-assertEq(view[163], 255, "163th value should be 255");
-assertEq(view[164], 230, "164th value should be 230");
-assertEq(view[165], 127, "165th value should be 127");
-assertEq(view[166], 25, "166th value should be 25");
-assertEq(view[167], 255, "167th value should be 255");
-assertEq(view[168], 205, "168th value should be 205");
-assertEq(view[169], 255, "169th value should be 255");
-assertEq(view[170], 50, "170th value should be 50");
-assertEq(view[171], 255, "171th value should be 255");
-assertEq(view[172], 205, "172th value should be 205");
-assertEq(view[173], 255, "173th value should be 255");
-assertEq(view[174], 50, "174th value should be 50");
-assertEq(view[175], 255, "175th value should be 255");
-assertEq(view[176], 205, "176th value should be 205");
-assertEq(view[177], 255, "177th value should be 255");
-assertEq(view[178], 50, "178th value should be 50");
-assertEq(view[179], 255, "179th value should be 255");
-assertEq(view[180], 205, "180th value should be 205");
-assertEq(view[181], 255, "181th value should be 255");
-assertEq(view[182], 50, "182th value should be 50");
-assertEq(view[183], 255, "183th value should be 255");
-assertEq(view[184], 205, "184th value should be 205");
-assertEq(view[185], 255, "185th value should be 255");
-assertEq(view[186], 50, "186th value should be 50");
-assertEq(view[187], 255, "187th value should be 255");
-assertEq(view[188], 179, "188th value should be 179");
-assertEq(view[189], 127, "189th value should be 127");
-assertEq(view[190], 76, "190th value should be 76");
-assertEq(view[191], 255, "191th value should be 255");
-assertEq(view[192], 179, "192th value should be 179");
-assertEq(view[193], 127, "193th value should be 127");
-assertEq(view[194], 76, "194th value should be 76");
-assertEq(view[195], 255, "195th value should be 255");
-assertEq(view[196], 154, "196th value should be 154");
-assertEq(view[197], 255, "197th value should be 255");
-assertEq(view[198], 101, "198th value should be 101");
-assertEq(view[199], 255, "199th value should be 255");
-assertEq(view[200], 103, "200th value should be 103");
-assertEq(view[201], 255, "201th value should be 255");
-assertEq(view[202], 152, "202th value should be 152");
-assertEq(view[203], 255, "203th value should be 255");
-assertEq(view[204], 78, "204th value should be 78");
-assertEq(view[205], 127, "205th value should be 127");
-assertEq(view[206], 178, "206th value should be 178");
-assertEq(view[207], 255, "207th value should be 255");
-assertEq(view[208], 0, "208th value should be 0");
-assertEq(view[209], 0, "209th value should be 0");
-assertEq(view[210], 0, "210th value should be 0");
-assertEq(view[211], 255, "211th value should be 255");
-assertEq(view[212], 0, "212th value should be 0");
-assertEq(view[213], 0, "213th value should be 0");
-assertEq(view[214], 0, "214th value should be 0");
-assertEq(view[215], 255, "215th value should be 255");
-assertEq(view[216], 78, "216th value should be 78");
-assertEq(view[217], 127, "217th value should be 127");
-assertEq(view[218], 178, "218th value should be 178");
-assertEq(view[219], 255, "219th value should be 255");
-assertEq(view[220], 128, "220th value should be 128");
-assertEq(view[221], 127, "221th value should be 127");
-assertEq(view[222], 127, "222th value should be 127");
-assertEq(view[223], 255, "223th value should be 255");
-assertEq(view[224], 154, "224th value should be 154");
-assertEq(view[225], 255, "225th value should be 255");
-assertEq(view[226], 101, "226th value should be 101");
-assertEq(view[227], 255, "227th value should be 255");
-assertEq(view[228], 205, "228th value should be 205");
-assertEq(view[229], 255, "229th value should be 255");
-assertEq(view[230], 50, "230th value should be 50");
-assertEq(view[231], 255, "231th value should be 255");
-assertEq(view[232], 205, "232th value should be 205");
-assertEq(view[233], 255, "233th value should be 255");
-assertEq(view[234], 50, "234th value should be 50");
-assertEq(view[235], 255, "235th value should be 255");
-assertEq(view[236], 230, "236th value should be 230");
-assertEq(view[237], 127, "237th value should be 127");
-assertEq(view[238], 25, "238th value should be 25");
-assertEq(view[239], 255, "239th value should be 255");
-assertEq(view[240], 0, "240th value should be 0");
-assertEq(view[241], 0, "241th value should be 0");
-assertEq(view[242], 0, "242th value should be 0");
-assertEq(view[243], 255, "243th value should be 255");
-assertEq(view[244], 205, "244th value should be 205");
-assertEq(view[245], 255, "245th value should be 255");
-assertEq(view[246], 50, "246th value should be 50");
-assertEq(view[247], 255, "247th value should be 255");
-assertEq(view[248], 205, "248th value should be 205");
-assertEq(view[249], 255, "249th value should be 255");
-assertEq(view[250], 50, "250th value should be 50");
-assertEq(view[251], 255, "251th value should be 255");
-assertEq(view[252], 205, "252th value should be 205");
-assertEq(view[253], 255, "253th value should be 255");
-assertEq(view[254], 50, "254th value should be 50");
-assertEq(view[255], 255, "255th value should be 255");
-assertEq(view[256], 205, "256th value should be 205");
-assertEq(view[257], 255, "257th value should be 255");
-assertEq(view[258], 50, "258th value should be 50");
-assertEq(view[259], 255, "259th value should be 255");
-assertEq(view[260], 205, "260th value should be 205");
-assertEq(view[261], 255, "261th value should be 255");
-assertEq(view[262], 50, "262th value should be 50");
-assertEq(view[263], 255, "263th value should be 255");
-assertEq(view[264], 179, "264th value should be 179");
-assertEq(view[265], 127, "265th value should be 127");
-assertEq(view[266], 76, "266th value should be 76");
-assertEq(view[267], 255, "267th value should be 255");
-assertEq(view[268], 179, "268th value should be 179");
-assertEq(view[269], 127, "269th value should be 127");
-assertEq(view[270], 76, "270th value should be 76");
-assertEq(view[271], 255, "271th value should be 255");
-assertEq(view[272], 154, "272th value should be 154");
-assertEq(view[273], 255, "273th value should be 255");
-assertEq(view[274], 101, "274th value should be 101");
-assertEq(view[275], 255, "275th value should be 255");
-assertEq(view[276], 52, "276th value should be 52");
-assertEq(view[277], 255, "277th value should be 255");
-assertEq(view[278], 203, "278th value should be 203");
-assertEq(view[279], 255, "279th value should be 255");
-assertEq(view[280], 0, "280th value should be 0");
-assertEq(view[281], 0, "281th value should be 0");
-assertEq(view[282], 0, "282th value should be 0");
-assertEq(view[283], 255, "283th value should be 255");
-assertEq(view[284], 0, "284th value should be 0");
-assertEq(view[285], 0, "285th value should be 0");
-assertEq(view[286], 0, "286th value should be 0");
-assertEq(view[287], 255, "287th value should be 255");
-assertEq(view[288], 0, "288th value should be 0");
-assertEq(view[289], 0, "289th value should be 0");
-assertEq(view[290], 0, "290th value should be 0");
-assertEq(view[291], 255, "291th value should be 255");
-assertEq(view[292], 0, "292th value should be 0");
-assertEq(view[293], 0, "293th value should be 0");
-assertEq(view[294], 0, "294th value should be 0");
-assertEq(view[295], 255, "295th value should be 255");
-assertEq(view[296], 0, "296th value should be 0");
-assertEq(view[297], 0, "297th value should be 0");
-assertEq(view[298], 0, "298th value should be 0");
-assertEq(view[299], 255, "299th value should be 255");
-assertEq(view[300], 52, "300th value should be 52");
-assertEq(view[301], 255, "301th value should be 255");
-assertEq(view[302], 203, "302th value should be 203");
-assertEq(view[303], 255, "303th value should be 255");
-assertEq(view[304], 52, "304th value should be 52");
-assertEq(view[305], 255, "305th value should be 255");
-assertEq(view[306], 203, "306th value should be 203");
-assertEq(view[307], 255, "307th value should be 255");
-assertEq(view[308], 179, "308th value should be 179");
-assertEq(view[309], 127, "309th value should be 127");
-assertEq(view[310], 76, "310th value should be 76");
-assertEq(view[311], 255, "311th value should be 255");
-assertEq(view[312], 205, "312th value should be 205");
-assertEq(view[313], 255, "313th value should be 255");
-assertEq(view[314], 50, "314th value should be 50");
-assertEq(view[315], 255, "315th value should be 255");
-assertEq(view[316], 205, "316th value should be 205");
-assertEq(view[317], 255, "317th value should be 255");
-assertEq(view[318], 50, "318th value should be 50");
-assertEq(view[319], 255, "319th value should be 255");
-assertEq(view[320], 230, "320th value should be 230");
-assertEq(view[321], 127, "321th value should be 127");
-assertEq(view[322], 25, "322th value should be 25");
-assertEq(view[323], 255, "323th value should be 255");
-assertEq(view[324], 205, "324th value should be 205");
-assertEq(view[325], 255, "325th value should be 255");
-assertEq(view[326], 50, "326th value should be 50");
-assertEq(view[327], 255, "327th value should be 255");
-assertEq(view[328], 205, "328th value should be 205");
-assertEq(view[329], 255, "329th value should be 255");
-assertEq(view[330], 50, "330th value should be 50");
-assertEq(view[331], 255, "331th value should be 255");
-assertEq(view[332], 205, "332th value should be 205");
-assertEq(view[333], 255, "333th value should be 255");
-assertEq(view[334], 50, "334th value should be 50");
-assertEq(view[335], 255, "335th value should be 255");
-assertEq(view[336], 205, "336th value should be 205");
-assertEq(view[337], 255, "337th value should be 255");
-assertEq(view[338], 50, "338th value should be 50");
-assertEq(view[339], 255, "339th value should be 255");
-assertEq(view[340], 179, "340th value should be 179");
-assertEq(view[341], 127, "341th value should be 127");
-assertEq(view[342], 76, "342th value should be 76");
-assertEq(view[343], 255, "343th value should be 255");
-assertEq(view[344], 154, "344th value should be 154");
-assertEq(view[345], 255, "345th value should be 255");
-assertEq(view[346], 101, "346th value should be 101");
-assertEq(view[347], 255, "347th value should be 255");
-assertEq(view[348], 154, "348th value should be 154");
-assertEq(view[349], 255, "349th value should be 255");
-assertEq(view[350], 101, "350th value should be 101");
-assertEq(view[351], 255, "351th value should be 255");
-assertEq(view[352], 128, "352th value should be 128");
-assertEq(view[353], 127, "353th value should be 127");
-assertEq(view[354], 127, "354th value should be 127");
-assertEq(view[355], 255, "355th value should be 255");
-assertEq(view[356], 52, "356th value should be 52");
-assertEq(view[357], 255, "357th value should be 255");
-assertEq(view[358], 203, "358th value should be 203");
-assertEq(view[359], 255, "359th value should be 255");
-assertEq(view[360], 0, "360th value should be 0");
-assertEq(view[361], 0, "361th value should be 0");
-assertEq(view[362], 0, "362th value should be 0");
-assertEq(view[363], 255, "363th value should be 255");
-assertEq(view[364], 0, "364th value should be 0");
-assertEq(view[365], 0, "365th value should be 0");
-assertEq(view[366], 0, "366th value should be 0");
-assertEq(view[367], 255, "367th value should be 255");
-assertEq(view[368], 0, "368th value should be 0");
-assertEq(view[369], 0, "369th value should be 0");
-assertEq(view[370], 0, "370th value should be 0");
-assertEq(view[371], 255, "371th value should be 255");
-assertEq(view[372], 0, "372th value should be 0");
-assertEq(view[373], 0, "373th value should be 0");
-assertEq(view[374], 0, "374th value should be 0");
-assertEq(view[375], 255, "375th value should be 255");
-assertEq(view[376], 0, "376th value should be 0");
-assertEq(view[377], 0, "377th value should be 0");
-assertEq(view[378], 0, "378th value should be 0");
-assertEq(view[379], 255, "379th value should be 255");
-assertEq(view[380], 0, "380th value should be 0");
-assertEq(view[381], 0, "381th value should be 0");
-assertEq(view[382], 0, "382th value should be 0");
-assertEq(view[383], 255, "383th value should be 255");
-assertEq(view[384], 52, "384th value should be 52");
-assertEq(view[385], 255, "385th value should be 255");
-assertEq(view[386], 203, "386th value should be 203");
-assertEq(view[387], 255, "387th value should be 255");
-assertEq(view[388], 179, "388th value should be 179");
-assertEq(view[389], 127, "389th value should be 127");
-assertEq(view[390], 76, "390th value should be 76");
-assertEq(view[391], 255, "391th value should be 255");
-assertEq(view[392], 205, "392th value should be 205");
-assertEq(view[393], 255, "393th value should be 255");
-assertEq(view[394], 50, "394th value should be 50");
-assertEq(view[395], 255, "395th value should be 255");
-assertEq(view[396], 205, "396th value should be 205");
-assertEq(view[397], 255, "397th value should be 255");
-assertEq(view[398], 50, "398th value should be 50");
-assertEq(view[399], 255, "399th value should be 255");
-assertEq(view[400], 205, "400th value should be 205");
-assertEq(view[401], 255, "401th value should be 255");
-assertEq(view[402], 50, "402th value should be 50");
-assertEq(view[403], 255, "403th value should be 255");
-assertEq(view[404], 205, "404th value should be 205");
-assertEq(view[405], 255, "405th value should be 255");
-assertEq(view[406], 50, "406th value should be 50");
-assertEq(view[407], 255, "407th value should be 255");
-assertEq(view[408], 205, "408th value should be 205");
-assertEq(view[409], 255, "409th value should be 255");
-assertEq(view[410], 50, "410th value should be 50");
-assertEq(view[411], 255, "411th value should be 255");
-assertEq(view[412], 205, "412th value should be 205");
-assertEq(view[413], 255, "413th value should be 255");
-assertEq(view[414], 50, "414th value should be 50");
-assertEq(view[415], 255, "415th value should be 255");
-assertEq(view[416], 154, "416th value should be 154");
-assertEq(view[417], 255, "417th value should be 255");
-assertEq(view[418], 101, "418th value should be 101");
-assertEq(view[419], 255, "419th value should be 255");
-assertEq(view[420], 128, "420th value should be 128");
-assertEq(view[421], 127, "421th value should be 127");
-assertEq(view[422], 127, "422th value should be 127");
-assertEq(view[423], 255, "423th value should be 255");
-assertEq(view[424], 154, "424th value should be 154");
-assertEq(view[425], 255, "425th value should be 255");
-assertEq(view[426], 101, "426th value should be 101");
-assertEq(view[427], 255, "427th value should be 255");
-assertEq(view[428], 128, "428th value should be 128");
-assertEq(view[429], 127, "429th value should be 127");
-assertEq(view[430], 127, "430th value should be 127");
-assertEq(view[431], 255, "431th value should be 255");
-assertEq(view[432], 103, "432th value should be 103");
-assertEq(view[433], 255, "433th value should be 255");
-assertEq(view[434], 152, "434th value should be 152");
-assertEq(view[435], 255, "435th value should be 255");
-assertEq(view[436], 0, "436th value should be 0");
-assertEq(view[437], 0, "437th value should be 0");
-assertEq(view[438], 0, "438th value should be 0");
-assertEq(view[439], 255, "439th value should be 255");
-assertEq(view[440], 0, "440th value should be 0");
-assertEq(view[441], 0, "441th value should be 0");
-assertEq(view[442], 0, "442th value should be 0");
-assertEq(view[443], 255, "443th value should be 255");
-assertEq(view[444], 0, "444th value should be 0");
-assertEq(view[445], 0, "445th value should be 0");
-assertEq(view[446], 0, "446th value should be 0");
-assertEq(view[447], 255, "447th value should be 255");
-assertEq(view[448], 0, "448th value should be 0");
-assertEq(view[449], 0, "449th value should be 0");
-assertEq(view[450], 0, "450th value should be 0");
-assertEq(view[451], 255, "451th value should be 255");
-assertEq(view[452], 0, "452th value should be 0");
-assertEq(view[453], 0, "453th value should be 0");
-assertEq(view[454], 0, "454th value should be 0");
-assertEq(view[455], 255, "455th value should be 255");
-assertEq(view[456], 0, "456th value should be 0");
-assertEq(view[457], 0, "457th value should be 0");
-assertEq(view[458], 0, "458th value should be 0");
-assertEq(view[459], 255, "459th value should be 255");
-assertEq(view[460], 0, "460th value should be 0");
-assertEq(view[461], 0, "461th value should be 0");
-assertEq(view[462], 0, "462th value should be 0");
-assertEq(view[463], 255, "463th value should be 255");
-assertEq(view[464], 78, "464th value should be 78");
-assertEq(view[465], 127, "465th value should be 127");
-assertEq(view[466], 178, "466th value should be 178");
-assertEq(view[467], 255, "467th value should be 255");
-assertEq(view[468], 154, "468th value should be 154");
-assertEq(view[469], 255, "469th value should be 255");
-assertEq(view[470], 101, "470th value should be 101");
-assertEq(view[471], 255, "471th value should be 255");
-assertEq(view[472], 205, "472th value should be 205");
-assertEq(view[473], 255, "473th value should be 255");
-assertEq(view[474], 50, "474th value should be 50");
-assertEq(view[475], 255, "475th value should be 255");
-assertEq(view[476], 205, "476th value should be 205");
-assertEq(view[477], 255, "477th value should be 255");
-assertEq(view[478], 50, "478th value should be 50");
-assertEq(view[479], 255, "479th value should be 255");
-assertEq(view[480], 205, "480th value should be 205");
-assertEq(view[481], 255, "481th value should be 255");
-assertEq(view[482], 50, "482th value should be 50");
-assertEq(view[483], 255, "483th value should be 255");
-assertEq(view[484], 205, "484th value should be 205");
-assertEq(view[485], 255, "485th value should be 255");
-assertEq(view[486], 50, "486th value should be 50");
-assertEq(view[487], 255, "487th value should be 255");
-assertEq(view[488], 179, "488th value should be 179");
-assertEq(view[489], 127, "489th value should be 127");
-assertEq(view[490], 76, "490th value should be 76");
-assertEq(view[491], 255, "491th value should be 255");
-assertEq(view[492], 179, "492th value should be 179");
-assertEq(view[493], 127, "493th value should be 127");
-assertEq(view[494], 76, "494th value should be 76");
-assertEq(view[495], 255, "495th value should be 255");
-assertEq(view[496], 128, "496th value should be 128");
-assertEq(view[497], 127, "497th value should be 127");
-assertEq(view[498], 127, "498th value should be 127");
-assertEq(view[499], 255, "499th value should be 255");
-assertEq(view[500], 52, "500th value should be 52");
-assertEq(view[501], 255, "501th value should be 255");
-assertEq(view[502], 203, "502th value should be 203");
-assertEq(view[503], 255, "503th value should be 255");
-assertEq(view[504], 0, "504th value should be 0");
-assertEq(view[505], 0, "505th value should be 0");
-assertEq(view[506], 0, "506th value should be 0");
-assertEq(view[507], 255, "507th value should be 255");
-assertEq(view[508], 78, "508th value should be 78");
-assertEq(view[509], 127, "509th value should be 127");
-assertEq(view[510], 178, "510th value should be 178");
-assertEq(view[511], 255, "511th value should be 255");
-assertEq(view[512], 52, "512th value should be 52");
-assertEq(view[513], 255, "513th value should be 255");
-assertEq(view[514], 203, "514th value should be 203");
-assertEq(view[515], 255, "515th value should be 255");
-assertEq(view[516], 0, "516th value should be 0");
-assertEq(view[517], 0, "517th value should be 0");
-assertEq(view[518], 0, "518th value should be 0");
-assertEq(view[519], 255, "519th value should be 255");
-assertEq(view[520], 0, "520th value should be 0");
-assertEq(view[521], 0, "521th value should be 0");
-assertEq(view[522], 0, "522th value should be 0");
-assertEq(view[523], 255, "523th value should be 255");
-assertEq(view[524], 0, "524th value should be 0");
-assertEq(view[525], 0, "525th value should be 0");
-assertEq(view[526], 0, "526th value should be 0");
-assertEq(view[527], 255, "527th value should be 255");
-assertEq(view[528], 0, "528th value should be 0");
-assertEq(view[529], 0, "529th value should be 0");
-assertEq(view[530], 0, "530th value should be 0");
-assertEq(view[531], 255, "531th value should be 255");
-assertEq(view[532], 0, "532th value should be 0");
-assertEq(view[533], 0, "533th value should be 0");
-assertEq(view[534], 0, "534th value should be 0");
-assertEq(view[535], 255, "535th value should be 255");
-assertEq(view[536], 0, "536th value should be 0");
-assertEq(view[537], 0, "537th value should be 0");
-assertEq(view[538], 0, "538th value should be 0");
-assertEq(view[539], 255, "539th value should be 255");
-assertEq(view[540], 0, "540th value should be 0");
-assertEq(view[541], 0, "541th value should be 0");
-assertEq(view[542], 0, "542th value should be 0");
-assertEq(view[543], 255, "543th value should be 255");
-assertEq(view[544], 0, "544th value should be 0");
-assertEq(view[545], 0, "545th value should be 0");
-assertEq(view[546], 0, "546th value should be 0");
-assertEq(view[547], 255, "547th value should be 255");
-assertEq(view[548], 154, "548th value should be 154");
-assertEq(view[549], 255, "549th value should be 255");
-assertEq(view[550], 101, "550th value should be 101");
-assertEq(view[551], 255, "551th value should be 255");
-assertEq(view[552], 205, "552th value should be 205");
-assertEq(view[553], 255, "553th value should be 255");
-assertEq(view[554], 50, "554th value should be 50");
-assertEq(view[555], 255, "555th value should be 255");
-assertEq(view[556], 205, "556th value should be 205");
-assertEq(view[557], 255, "557th value should be 255");
-assertEq(view[558], 50, "558th value should be 50");
-assertEq(view[559], 255, "559th value should be 255");
-assertEq(view[560], 205, "560th value should be 205");
-assertEq(view[561], 255, "561th value should be 255");
-assertEq(view[562], 50, "562th value should be 50");
-assertEq(view[563], 255, "563th value should be 255");
-assertEq(view[564], 179, "564th value should be 179");
-assertEq(view[565], 127, "565th value should be 127");
-assertEq(view[566], 76, "566th value should be 76");
-assertEq(view[567], 255, "567th value should be 255");
-assertEq(view[568], 179, "568th value should be 179");
-assertEq(view[569], 127, "569th value should be 127");
-assertEq(view[570], 76, "570th value should be 76");
-assertEq(view[571], 255, "571th value should be 255");
-assertEq(view[572], 154, "572th value should be 154");
-assertEq(view[573], 255, "573th value should be 255");
-assertEq(view[574], 101, "574th value should be 101");
-assertEq(view[575], 255, "575th value should be 255");
-assertEq(view[576], 103, "576th value should be 103");
-assertEq(view[577], 255, "577th value should be 255");
-assertEq(view[578], 152, "578th value should be 152");
-assertEq(view[579], 255, "579th value should be 255");
-assertEq(view[580], 0, "580th value should be 0");
-assertEq(view[581], 0, "581th value should be 0");
-assertEq(view[582], 0, "582th value should be 0");
-assertEq(view[583], 255, "583th value should be 255");
-assertEq(view[584], 0, "584th value should be 0");
-assertEq(view[585], 0, "585th value should be 0");
-assertEq(view[586], 0, "586th value should be 0");
-assertEq(view[587], 255, "587th value should be 255");
-assertEq(view[588], 0, "588th value should be 0");
-assertEq(view[589], 0, "589th value should be 0");
-assertEq(view[590], 0, "590th value should be 0");
-assertEq(view[591], 255, "591th value should be 255");
-assertEq(view[592], 0, "592th value should be 0");
-assertEq(view[593], 0, "593th value should be 0");
-assertEq(view[594], 0, "594th value should be 0");
-assertEq(view[595], 255, "595th value should be 255");
-assertEq(view[596], 0, "596th value should be 0");
-assertEq(view[597], 0, "597th value should be 0");
-assertEq(view[598], 0, "598th value should be 0");
-assertEq(view[599], 255, "599th value should be 255");
-assertEq(view[600], 0, "600th value should be 0");
-assertEq(view[601], 0, "601th value should be 0");
-assertEq(view[602], 0, "602th value should be 0");
-assertEq(view[603], 255, "603th value should be 255");
-assertEq(view[604], 0, "604th value should be 0");
-assertEq(view[605], 0, "605th value should be 0");
-assertEq(view[606], 0, "606th value should be 0");
-assertEq(view[607], 255, "607th value should be 255");
-assertEq(view[608], 0, "608th value should be 0");
-assertEq(view[609], 0, "609th value should be 0");
-assertEq(view[610], 0, "610th value should be 0");
-assertEq(view[611], 255, "611th value should be 255");
-assertEq(view[612], 0, "612th value should be 0");
-assertEq(view[613], 0, "613th value should be 0");
-assertEq(view[614], 0, "614th value should be 0");
-assertEq(view[615], 255, "615th value should be 255");
-assertEq(view[616], 0, "616th value should be 0");
-assertEq(view[617], 0, "617th value should be 0");
-assertEq(view[618], 0, "618th value should be 0");
-assertEq(view[619], 255, "619th value should be 255");
-assertEq(view[620], 0, "620th value should be 0");
-assertEq(view[621], 0, "621th value should be 0");
-assertEq(view[622], 0, "622th value should be 0");
-assertEq(view[623], 255, "623th value should be 255");
-assertEq(view[624], 0, "624th value should be 0");
-assertEq(view[625], 0, "625th value should be 0");
-assertEq(view[626], 0, "626th value should be 0");
-assertEq(view[627], 255, "627th value should be 255");
-assertEq(view[628], 154, "628th value should be 154");
-assertEq(view[629], 255, "629th value should be 255");
-assertEq(view[630], 101, "630th value should be 101");
-assertEq(view[631], 255, "631th value should be 255");
-assertEq(view[632], 205, "632th value should be 205");
-assertEq(view[633], 255, "633th value should be 255");
-assertEq(view[634], 50, "634th value should be 50");
-assertEq(view[635], 255, "635th value should be 255");
-assertEq(view[636], 205, "636th value should be 205");
-assertEq(view[637], 255, "637th value should be 255");
-assertEq(view[638], 50, "638th value should be 50");
-assertEq(view[639], 255, "639th value should be 255");
-assertEq(view[640], 179, "640th value should be 179");
-assertEq(view[641], 127, "641th value should be 127");
-assertEq(view[642], 76, "642th value should be 76");
-assertEq(view[643], 255, "643th value should be 255");
-assertEq(view[644], 179, "644th value should be 179");
-assertEq(view[645], 127, "645th value should be 127");
-assertEq(view[646], 76, "646th value should be 76");
-assertEq(view[647], 255, "647th value should be 255");
-assertEq(view[648], 154, "648th value should be 154");
-assertEq(view[649], 255, "649th value should be 255");
-assertEq(view[650], 101, "650th value should be 101");
-assertEq(view[651], 255, "651th value should be 255");
-assertEq(view[652], 128, "652th value should be 128");
-assertEq(view[653], 127, "653th value should be 127");
-assertEq(view[654], 127, "654th value should be 127");
-assertEq(view[655], 255, "655th value should be 255");
-assertEq(view[656], 52, "656th value should be 52");
-assertEq(view[657], 255, "657th value should be 255");
-assertEq(view[658], 203, "658th value should be 203");
-assertEq(view[659], 255, "659th value should be 255");
-assertEq(view[660], 0, "660th value should be 0");
-assertEq(view[661], 0, "661th value should be 0");
-assertEq(view[662], 0, "662th value should be 0");
-assertEq(view[663], 255, "663th value should be 255");
-assertEq(view[664], 0, "664th value should be 0");
-assertEq(view[665], 0, "665th value should be 0");
-assertEq(view[666], 0, "666th value should be 0");
-assertEq(view[667], 255, "667th value should be 255");
-assertEq(view[668], 0, "668th value should be 0");
-assertEq(view[669], 0, "669th value should be 0");
-assertEq(view[670], 0, "670th value should be 0");
-assertEq(view[671], 255, "671th value should be 255");
-assertEq(view[672], 0, "672th value should be 0");
-assertEq(view[673], 0, "673th value should be 0");
-assertEq(view[674], 0, "674th value should be 0");
-assertEq(view[675], 255, "675th value should be 255");
-assertEq(view[676], 0, "676th value should be 0");
-assertEq(view[677], 0, "677th value should be 0");
-assertEq(view[678], 0, "678th value should be 0");
-assertEq(view[679], 255, "679th value should be 255");
-assertEq(view[680], 0, "680th value should be 0");
-assertEq(view[681], 0, "681th value should be 0");
-assertEq(view[682], 0, "682th value should be 0");
-assertEq(view[683], 255, "683th value should be 255");
-assertEq(view[684], 0, "684th value should be 0");
-assertEq(view[685], 0, "685th value should be 0");
-assertEq(view[686], 0, "686th value should be 0");
-assertEq(view[687], 255, "687th value should be 255");
-assertEq(view[688], 0, "688th value should be 0");
-assertEq(view[689], 0, "689th value should be 0");
-assertEq(view[690], 0, "690th value should be 0");
-assertEq(view[691], 255, "691th value should be 255");
-assertEq(view[692], 0, "692th value should be 0");
-assertEq(view[693], 0, "693th value should be 0");
-assertEq(view[694], 0, "694th value should be 0");
-assertEq(view[695], 255, "695th value should be 255");
-assertEq(view[696], 0, "696th value should be 0");
-assertEq(view[697], 0, "697th value should be 0");
-assertEq(view[698], 0, "698th value should be 0");
-assertEq(view[699], 255, "699th value should be 255");
-assertEq(view[700], 0, "700th value should be 0");
-assertEq(view[701], 0, "701th value should be 0");
-assertEq(view[702], 0, "702th value should be 0");
-assertEq(view[703], 255, "703th value should be 255");
-assertEq(view[704], 0, "704th value should be 0");
-assertEq(view[705], 0, "705th value should be 0");
-assertEq(view[706], 0, "706th value should be 0");
-assertEq(view[707], 255, "707th value should be 255");
-assertEq(view[708], 154, "708th value should be 154");
-assertEq(view[709], 255, "709th value should be 255");
-assertEq(view[710], 101, "710th value should be 101");
-assertEq(view[711], 255, "711th value should be 255");
-assertEq(view[712], 179, "712th value should be 179");
-assertEq(view[713], 127, "713th value should be 127");
-assertEq(view[714], 76, "714th value should be 76");
-assertEq(view[715], 255, "715th value should be 255");
-assertEq(view[716], 205, "716th value should be 205");
-assertEq(view[717], 255, "717th value should be 255");
-assertEq(view[718], 50, "718th value should be 50");
-assertEq(view[719], 255, "719th value should be 255");
-assertEq(view[720], 154, "720th value should be 154");
-assertEq(view[721], 255, "721th value should be 255");
-assertEq(view[722], 101, "722th value should be 101");
-assertEq(view[723], 255, "723th value should be 255");
-assertEq(view[724], 52, "724th value should be 52");
-assertEq(view[725], 255, "725th value should be 255");
-assertEq(view[726], 203, "726th value should be 203");
-assertEq(view[727], 255, "727th value should be 255");
-assertEq(view[728], 128, "728th value should be 128");
-assertEq(view[729], 127, "729th value should be 127");
-assertEq(view[730], 127, "730th value should be 127");
-assertEq(view[731], 255, "731th value should be 255");
-assertEq(view[732], 78, "732th value should be 78");
-assertEq(view[733], 127, "733th value should be 127");
-assertEq(view[734], 178, "734th value should be 178");
-assertEq(view[735], 255, "735th value should be 255");
-assertEq(view[736], 0, "736th value should be 0");
-assertEq(view[737], 0, "737th value should be 0");
-assertEq(view[738], 0, "738th value should be 0");
-assertEq(view[739], 255, "739th value should be 255");
-assertEq(view[740], 0, "740th value should be 0");
-assertEq(view[741], 0, "741th value should be 0");
-assertEq(view[742], 0, "742th value should be 0");
-assertEq(view[743], 255, "743th value should be 255");
-assertEq(view[744], 0, "744th value should be 0");
-assertEq(view[745], 0, "745th value should be 0");
-assertEq(view[746], 0, "746th value should be 0");
-assertEq(view[747], 255, "747th value should be 255");
-assertEq(view[748], 0, "748th value should be 0");
-assertEq(view[749], 0, "749th value should be 0");
-assertEq(view[750], 0, "750th value should be 0");
-assertEq(view[751], 255, "751th value should be 255");
-assertEq(view[752], 0, "752th value should be 0");
-assertEq(view[753], 0, "753th value should be 0");
-assertEq(view[754], 0, "754th value should be 0");
-assertEq(view[755], 255, "755th value should be 255");
-assertEq(view[756], 0, "756th value should be 0");
-assertEq(view[757], 0, "757th value should be 0");
-assertEq(view[758], 0, "758th value should be 0");
-assertEq(view[759], 255, "759th value should be 255");
-assertEq(view[760], 0, "760th value should be 0");
-assertEq(view[761], 0, "761th value should be 0");
-assertEq(view[762], 0, "762th value should be 0");
-assertEq(view[763], 255, "763th value should be 255");
-assertEq(view[764], 0, "764th value should be 0");
-assertEq(view[765], 0, "765th value should be 0");
-assertEq(view[766], 0, "766th value should be 0");
-assertEq(view[767], 255, "767th value should be 255");
-assertEq(view[768], 0, "768th value should be 0");
-assertEq(view[769], 0, "769th value should be 0");
-assertEq(view[770], 0, "770th value should be 0");
-assertEq(view[771], 255, "771th value should be 255");
-assertEq(view[772], 0, "772th value should be 0");
-assertEq(view[773], 0, "773th value should be 0");
-assertEq(view[774], 0, "774th value should be 0");
-assertEq(view[775], 255, "775th value should be 255");
-assertEq(view[776], 0, "776th value should be 0");
-assertEq(view[777], 0, "777th value should be 0");
-assertEq(view[778], 0, "778th value should be 0");
-assertEq(view[779], 255, "779th value should be 255");
-assertEq(view[780], 0, "780th value should be 0");
-assertEq(view[781], 0, "781th value should be 0");
-assertEq(view[782], 0, "782th value should be 0");
-assertEq(view[783], 255, "783th value should be 255");
-assertEq(view[784], 78, "784th value should be 78");
-assertEq(view[785], 127, "785th value should be 127");
-assertEq(view[786], 178, "786th value should be 178");
-assertEq(view[787], 255, "787th value should be 255");
-assertEq(view[788], 154, "788th value should be 154");
-assertEq(view[789], 255, "789th value should be 255");
-assertEq(view[790], 101, "790th value should be 101");
-assertEq(view[791], 255, "791th value should be 255");
-assertEq(view[792], 179, "792th value should be 179");
-assertEq(view[793], 127, "793th value should be 127");
-assertEq(view[794], 76, "794th value should be 76");
-assertEq(view[795], 255, "795th value should be 255");
-assertEq(view[796], 205, "796th value should be 205");
-assertEq(view[797], 255, "797th value should be 255");
-assertEq(view[798], 50, "798th value should be 50");
-assertEq(view[799], 255, "799th value should be 255");
-assertEq(view[800], 128, "800th value should be 128");
-assertEq(view[801], 127, "801th value should be 127");
-assertEq(view[802], 127, "802th value should be 127");
-assertEq(view[803], 255, "803th value should be 255");
-assertEq(view[804], 0, "804th value should be 0");
-assertEq(view[805], 0, "805th value should be 0");
-assertEq(view[806], 0, "806th value should be 0");
-assertEq(view[807], 255, "807th value should be 255");
-assertEq(view[808], 26, "808th value should be 26");
-assertEq(view[809], 127, "809th value should be 127");
-assertEq(view[810], 229, "810th value should be 229");
-assertEq(view[811], 255, "811th value should be 255");
-assertEq(view[812], 0, "812th value should be 0");
-assertEq(view[813], 0, "813th value should be 0");
-assertEq(view[814], 0, "814th value should be 0");
-assertEq(view[815], 255, "815th value should be 255");
-assertEq(view[816], 0, "816th value should be 0");
-assertEq(view[817], 0, "817th value should be 0");
-assertEq(view[818], 0, "818th value should be 0");
-assertEq(view[819], 255, "819th value should be 255");
-assertEq(view[820], 0, "820th value should be 0");
-assertEq(view[821], 0, "821th value should be 0");
-assertEq(view[822], 0, "822th value should be 0");
-assertEq(view[823], 255, "823th value should be 255");
-assertEq(view[824], 0, "824th value should be 0");
-assertEq(view[825], 0, "825th value should be 0");
-assertEq(view[826], 0, "826th value should be 0");
-assertEq(view[827], 255, "827th value should be 255");
-assertEq(view[828], 0, "828th value should be 0");
-assertEq(view[829], 0, "829th value should be 0");
-assertEq(view[830], 0, "830th value should be 0");
-assertEq(view[831], 255, "831th value should be 255");
-assertEq(view[832], 0, "832th value should be 0");
-assertEq(view[833], 0, "833th value should be 0");
-assertEq(view[834], 0, "834th value should be 0");
-assertEq(view[835], 255, "835th value should be 255");
-assertEq(view[836], 0, "836th value should be 0");
-assertEq(view[837], 0, "837th value should be 0");
-assertEq(view[838], 0, "838th value should be 0");
-assertEq(view[839], 255, "839th value should be 255");
-assertEq(view[840], 0, "840th value should be 0");
-assertEq(view[841], 0, "841th value should be 0");
-assertEq(view[842], 0, "842th value should be 0");
-assertEq(view[843], 255, "843th value should be 255");
-assertEq(view[844], 0, "844th value should be 0");
-assertEq(view[845], 0, "845th value should be 0");
-assertEq(view[846], 0, "846th value should be 0");
-assertEq(view[847], 255, "847th value should be 255");
-assertEq(view[848], 0, "848th value should be 0");
-assertEq(view[849], 0, "849th value should be 0");
-assertEq(view[850], 0, "850th value should be 0");
-assertEq(view[851], 255, "851th value should be 255");
-assertEq(view[852], 0, "852th value should be 0");
-assertEq(view[853], 0, "853th value should be 0");
-assertEq(view[854], 0, "854th value should be 0");
-assertEq(view[855], 255, "855th value should be 255");
-assertEq(view[856], 0, "856th value should be 0");
-assertEq(view[857], 0, "857th value should be 0");
-assertEq(view[858], 0, "858th value should be 0");
-assertEq(view[859], 255, "859th value should be 255");
-assertEq(view[860], 0, "860th value should be 0");
-assertEq(view[861], 0, "861th value should be 0");
-assertEq(view[862], 0, "862th value should be 0");
-assertEq(view[863], 255, "863th value should be 255");
-assertEq(view[864], 103, "864th value should be 103");
-assertEq(view[865], 255, "865th value should be 255");
-assertEq(view[866], 152, "866th value should be 152");
-assertEq(view[867], 255, "867th value should be 255");
-assertEq(view[868], 154, "868th value should be 154");
-assertEq(view[869], 255, "869th value should be 255");
-assertEq(view[870], 101, "870th value should be 101");
-assertEq(view[871], 255, "871th value should be 255");
-assertEq(view[872], 179, "872th value should be 179");
-assertEq(view[873], 127, "873th value should be 127");
-assertEq(view[874], 76, "874th value should be 76");
-assertEq(view[875], 255, "875th value should be 255");
-assertEq(view[876], 205, "876th value should be 205");
-assertEq(view[877], 255, "877th value should be 255");
-assertEq(view[878], 50, "878th value should be 50");
-assertEq(view[879], 255, "879th value should be 255");
-assertEq(view[880], 179, "880th value should be 179");
-assertEq(view[881], 127, "881th value should be 127");
-assertEq(view[882], 76, "882th value should be 76");
-assertEq(view[883], 255, "883th value should be 255");
-assertEq(view[884], 179, "884th value should be 179");
-assertEq(view[885], 127, "885th value should be 127");
-assertEq(view[886], 76, "886th value should be 76");
-assertEq(view[887], 255, "887th value should be 255");
-assertEq(view[888], 128, "888th value should be 128");
-assertEq(view[889], 127, "889th value should be 127");
-assertEq(view[890], 127, "890th value should be 127");
-assertEq(view[891], 255, "891th value should be 255");
-assertEq(view[892], 103, "892th value should be 103");
-assertEq(view[893], 255, "893th value should be 255");
-assertEq(view[894], 152, "894th value should be 152");
-assertEq(view[895], 255, "895th value should be 255");
-assertEq(view[896], 26, "896th value should be 26");
-assertEq(view[897], 127, "897th value should be 127");
-assertEq(view[898], 229, "898th value should be 229");
-assertEq(view[899], 255, "899th value should be 255");
-assertEq(view[900], 0, "900th value should be 0");
-assertEq(view[901], 0, "901th value should be 0");
-assertEq(view[902], 0, "902th value should be 0");
-assertEq(view[903], 255, "903th value should be 255");
-assertEq(view[904], 0, "904th value should be 0");
-assertEq(view[905], 0, "905th value should be 0");
-assertEq(view[906], 0, "906th value should be 0");
-assertEq(view[907], 255, "907th value should be 255");
-assertEq(view[908], 0, "908th value should be 0");
-assertEq(view[909], 0, "909th value should be 0");
-assertEq(view[910], 0, "910th value should be 0");
-assertEq(view[911], 255, "911th value should be 255");
-assertEq(view[912], 0, "912th value should be 0");
-assertEq(view[913], 0, "913th value should be 0");
-assertEq(view[914], 0, "914th value should be 0");
-assertEq(view[915], 255, "915th value should be 255");
-assertEq(view[916], 0, "916th value should be 0");
-assertEq(view[917], 0, "917th value should be 0");
-assertEq(view[918], 0, "918th value should be 0");
-assertEq(view[919], 255, "919th value should be 255");
-assertEq(view[920], 0, "920th value should be 0");
-assertEq(view[921], 0, "921th value should be 0");
-assertEq(view[922], 0, "922th value should be 0");
-assertEq(view[923], 255, "923th value should be 255");
-assertEq(view[924], 0, "924th value should be 0");
-assertEq(view[925], 0, "925th value should be 0");
-assertEq(view[926], 0, "926th value should be 0");
-assertEq(view[927], 255, "927th value should be 255");
-assertEq(view[928], 0, "928th value should be 0");
-assertEq(view[929], 0, "929th value should be 0");
-assertEq(view[930], 0, "930th value should be 0");
-assertEq(view[931], 255, "931th value should be 255");
-assertEq(view[932], 0, "932th value should be 0");
-assertEq(view[933], 0, "933th value should be 0");
-assertEq(view[934], 0, "934th value should be 0");
-assertEq(view[935], 255, "935th value should be 255");
-assertEq(view[936], 0, "936th value should be 0");
-assertEq(view[937], 0, "937th value should be 0");
-assertEq(view[938], 0, "938th value should be 0");
-assertEq(view[939], 255, "939th value should be 255");
-assertEq(view[940], 0, "940th value should be 0");
-assertEq(view[941], 0, "941th value should be 0");
-assertEq(view[942], 0, "942th value should be 0");
-assertEq(view[943], 255, "943th value should be 255");
-assertEq(view[944], 0, "944th value should be 0");
-assertEq(view[945], 0, "945th value should be 0");
-assertEq(view[946], 0, "946th value should be 0");
-assertEq(view[947], 255, "947th value should be 255");
-assertEq(view[948], 154, "948th value should be 154");
-assertEq(view[949], 255, "949th value should be 255");
-assertEq(view[950], 101, "950th value should be 101");
-assertEq(view[951], 255, "951th value should be 255");
-assertEq(view[952], 179, "952th value should be 179");
-assertEq(view[953], 127, "953th value should be 127");
-assertEq(view[954], 76, "954th value should be 76");
-assertEq(view[955], 255, "955th value should be 255");
-assertEq(view[956], 205, "956th value should be 205");
-assertEq(view[957], 255, "957th value should be 255");
-assertEq(view[958], 50, "958th value should be 50");
-assertEq(view[959], 255, "959th value should be 255");
-assertEq(view[960], 179, "960th value should be 179");
-assertEq(view[961], 127, "961th value should be 127");
-assertEq(view[962], 76, "962th value should be 76");
-assertEq(view[963], 255, "963th value should be 255");
-assertEq(view[964], 179, "964th value should be 179");
-assertEq(view[965], 127, "965th value should be 127");
-assertEq(view[966], 76, "966th value should be 76");
-assertEq(view[967], 255, "967th value should be 255");
-assertEq(view[968], 179, "968th value should be 179");
-assertEq(view[969], 127, "969th value should be 127");
-assertEq(view[970], 76, "970th value should be 76");
-assertEq(view[971], 255, "971th value should be 255");
-assertEq(view[972], 154, "972th value should be 154");
-assertEq(view[973], 255, "973th value should be 255");
-assertEq(view[974], 101, "974th value should be 101");
-assertEq(view[975], 255, "975th value should be 255");
-assertEq(view[976], 103, "976th value should be 103");
-assertEq(view[977], 255, "977th value should be 255");
-assertEq(view[978], 152, "978th value should be 152");
-assertEq(view[979], 255, "979th value should be 255");
-assertEq(view[980], 0, "980th value should be 0");
-assertEq(view[981], 0, "981th value should be 0");
-assertEq(view[982], 0, "982th value should be 0");
-assertEq(view[983], 255, "983th value should be 255");
-assertEq(view[984], 0, "984th value should be 0");
-assertEq(view[985], 0, "985th value should be 0");
-assertEq(view[986], 0, "986th value should be 0");
-assertEq(view[987], 255, "987th value should be 255");
-assertEq(view[988], 0, "988th value should be 0");
-assertEq(view[989], 0, "989th value should be 0");
-assertEq(view[990], 0, "990th value should be 0");
-assertEq(view[991], 255, "991th value should be 255");
-assertEq(view[992], 0, "992th value should be 0");
-assertEq(view[993], 0, "993th value should be 0");
-assertEq(view[994], 0, "994th value should be 0");
-assertEq(view[995], 255, "995th value should be 255");
-assertEq(view[996], 0, "996th value should be 0");
-assertEq(view[997], 0, "997th value should be 0");
-assertEq(view[998], 0, "998th value should be 0");
-assertEq(view[999], 255, "999th value should be 255");
-assertEq(view[1000], 0, "1000th value should be 0");
-assertEq(view[1001], 0, "1001th value should be 0");
-assertEq(view[1002], 0, "1002th value should be 0");
-assertEq(view[1003], 255, "1003th value should be 255");
-assertEq(view[1004], 0, "1004th value should be 0");
-assertEq(view[1005], 0, "1005th value should be 0");
-assertEq(view[1006], 0, "1006th value should be 0");
-assertEq(view[1007], 255, "1007th value should be 255");
-assertEq(view[1008], 0, "1008th value should be 0");
-assertEq(view[1009], 0, "1009th value should be 0");
-assertEq(view[1010], 0, "1010th value should be 0");
-assertEq(view[1011], 255, "1011th value should be 255");
-assertEq(view[1012], 0, "1012th value should be 0");
-assertEq(view[1013], 0, "1013th value should be 0");
-assertEq(view[1014], 0, "1014th value should be 0");
-assertEq(view[1015], 255, "1015th value should be 255");
-assertEq(view[1016], 0, "1016th value should be 0");
-assertEq(view[1017], 0, "1017th value should be 0");
-assertEq(view[1018], 0, "1018th value should be 0");
-assertEq(view[1019], 255, "1019th value should be 255");
-assertEq(view[1020], 0, "1020th value should be 0");
-assertEq(view[1021], 0, "1021th value should be 0");
-assertEq(view[1022], 0, "1022th value should be 0");
-assertEq(view[1023], 255, "1023th value should be 255");
-assertEq(view[1024], 0, "1024th value should be 0");
-assertEq(view[1025], 0, "1025th value should be 0");
-assertEq(view[1026], 0, "1026th value should be 0");
-assertEq(view[1027], 255, "1027th value should be 255");
-assertEq(view[1028], 154, "1028th value should be 154");
-assertEq(view[1029], 255, "1029th value should be 255");
-assertEq(view[1030], 101, "1030th value should be 101");
-assertEq(view[1031], 255, "1031th value should be 255");
-assertEq(view[1032], 205, "1032th value should be 205");
-assertEq(view[1033], 255, "1033th value should be 255");
-assertEq(view[1034], 50, "1034th value should be 50");
-assertEq(view[1035], 255, "1035th value should be 255");
-assertEq(view[1036], 205, "1036th value should be 205");
-assertEq(view[1037], 255, "1037th value should be 255");
-assertEq(view[1038], 50, "1038th value should be 50");
-assertEq(view[1039], 255, "1039th value should be 255");
-assertEq(view[1040], 205, "1040th value should be 205");
-assertEq(view[1041], 255, "1041th value should be 255");
-assertEq(view[1042], 50, "1042th value should be 50");
-assertEq(view[1043], 255, "1043th value should be 255");
-assertEq(view[1044], 179, "1044th value should be 179");
-assertEq(view[1045], 127, "1045th value should be 127");
-assertEq(view[1046], 76, "1046th value should be 76");
-assertEq(view[1047], 255, "1047th value should be 255");
-assertEq(view[1048], 179, "1048th value should be 179");
-assertEq(view[1049], 127, "1049th value should be 127");
-assertEq(view[1050], 76, "1050th value should be 76");
-assertEq(view[1051], 255, "1051th value should be 255");
-assertEq(view[1052], 154, "1052th value should be 154");
-assertEq(view[1053], 255, "1053th value should be 255");
-assertEq(view[1054], 101, "1054th value should be 101");
-assertEq(view[1055], 255, "1055th value should be 255");
-assertEq(view[1056], 128, "1056th value should be 128");
-assertEq(view[1057], 127, "1057th value should be 127");
-assertEq(view[1058], 127, "1058th value should be 127");
-assertEq(view[1059], 255, "1059th value should be 255");
-assertEq(view[1060], 0, "1060th value should be 0");
-assertEq(view[1061], 0, "1061th value should be 0");
-assertEq(view[1062], 0, "1062th value should be 0");
-assertEq(view[1063], 255, "1063th value should be 255");
-assertEq(view[1064], 0, "1064th value should be 0");
-assertEq(view[1065], 0, "1065th value should be 0");
-assertEq(view[1066], 0, "1066th value should be 0");
-assertEq(view[1067], 255, "1067th value should be 255");
-assertEq(view[1068], 26, "1068th value should be 26");
-assertEq(view[1069], 127, "1069th value should be 127");
-assertEq(view[1070], 229, "1070th value should be 229");
-assertEq(view[1071], 255, "1071th value should be 255");
-assertEq(view[1072], 26, "1072th value should be 26");
-assertEq(view[1073], 127, "1073th value should be 127");
-assertEq(view[1074], 229, "1074th value should be 229");
-assertEq(view[1075], 255, "1075th value should be 255");
-assertEq(view[1076], 0, "1076th value should be 0");
-assertEq(view[1077], 0, "1077th value should be 0");
-assertEq(view[1078], 0, "1078th value should be 0");
-assertEq(view[1079], 255, "1079th value should be 255");
-assertEq(view[1080], 0, "1080th value should be 0");
-assertEq(view[1081], 0, "1081th value should be 0");
-assertEq(view[1082], 0, "1082th value should be 0");
-assertEq(view[1083], 255, "1083th value should be 255");
-assertEq(view[1084], 0, "1084th value should be 0");
-assertEq(view[1085], 0, "1085th value should be 0");
-assertEq(view[1086], 0, "1086th value should be 0");
-assertEq(view[1087], 255, "1087th value should be 255");
-assertEq(view[1088], 0, "1088th value should be 0");
-assertEq(view[1089], 0, "1089th value should be 0");
-assertEq(view[1090], 0, "1090th value should be 0");
-assertEq(view[1091], 255, "1091th value should be 255");
-assertEq(view[1092], 0, "1092th value should be 0");
-assertEq(view[1093], 0, "1093th value should be 0");
-assertEq(view[1094], 0, "1094th value should be 0");
-assertEq(view[1095], 255, "1095th value should be 255");
-assertEq(view[1096], 0, "1096th value should be 0");
-assertEq(view[1097], 0, "1097th value should be 0");
-assertEq(view[1098], 0, "1098th value should be 0");
-assertEq(view[1099], 255, "1099th value should be 255");
-assertEq(view[1100], 0, "1100th value should be 0");
-assertEq(view[1101], 0, "1101th value should be 0");
-assertEq(view[1102], 0, "1102th value should be 0");
-assertEq(view[1103], 255, "1103th value should be 255");
-assertEq(view[1104], 0, "1104th value should be 0");
-assertEq(view[1105], 0, "1105th value should be 0");
-assertEq(view[1106], 0, "1106th value should be 0");
-assertEq(view[1107], 255, "1107th value should be 255");
-assertEq(view[1108], 154, "1108th value should be 154");
-assertEq(view[1109], 255, "1109th value should be 255");
-assertEq(view[1110], 101, "1110th value should be 101");
-assertEq(view[1111], 255, "1111th value should be 255");
-assertEq(view[1112], 205, "1112th value should be 205");
-assertEq(view[1113], 255, "1113th value should be 255");
-assertEq(view[1114], 50, "1114th value should be 50");
-assertEq(view[1115], 255, "1115th value should be 255");
-assertEq(view[1116], 205, "1116th value should be 205");
-assertEq(view[1117], 255, "1117th value should be 255");
-assertEq(view[1118], 50, "1118th value should be 50");
-assertEq(view[1119], 255, "1119th value should be 255");
-assertEq(view[1120], 205, "1120th value should be 205");
-assertEq(view[1121], 255, "1121th value should be 255");
-assertEq(view[1122], 50, "1122th value should be 50");
-assertEq(view[1123], 255, "1123th value should be 255");
-assertEq(view[1124], 205, "1124th value should be 205");
-assertEq(view[1125], 255, "1125th value should be 255");
-assertEq(view[1126], 50, "1126th value should be 50");
-assertEq(view[1127], 255, "1127th value should be 255");
-assertEq(view[1128], 205, "1128th value should be 205");
-assertEq(view[1129], 255, "1129th value should be 255");
-assertEq(view[1130], 50, "1130th value should be 50");
-assertEq(view[1131], 255, "1131th value should be 255");
-assertEq(view[1132], 179, "1132th value should be 179");
-assertEq(view[1133], 127, "1133th value should be 127");
-assertEq(view[1134], 76, "1134th value should be 76");
-assertEq(view[1135], 255, "1135th value should be 255");
-assertEq(view[1136], 154, "1136th value should be 154");
-assertEq(view[1137], 255, "1137th value should be 255");
-assertEq(view[1138], 101, "1138th value should be 101");
-assertEq(view[1139], 255, "1139th value should be 255");
-assertEq(view[1140], 128, "1140th value should be 128");
-assertEq(view[1141], 127, "1141th value should be 127");
-assertEq(view[1142], 127, "1142th value should be 127");
-assertEq(view[1143], 255, "1143th value should be 255");
-assertEq(view[1144], 128, "1144th value should be 128");
-assertEq(view[1145], 127, "1145th value should be 127");
-assertEq(view[1146], 127, "1146th value should be 127");
-assertEq(view[1147], 255, "1147th value should be 255");
-assertEq(view[1148], 103, "1148th value should be 103");
-assertEq(view[1149], 255, "1149th value should be 255");
-assertEq(view[1150], 152, "1150th value should be 152");
-assertEq(view[1151], 255, "1151th value should be 255");
-assertEq(view[1152], 78, "1152th value should be 78");
-assertEq(view[1153], 127, "1153th value should be 127");
-assertEq(view[1154], 178, "1154th value should be 178");
-assertEq(view[1155], 255, "1155th value should be 255");
-assertEq(view[1156], 0, "1156th value should be 0");
-assertEq(view[1157], 0, "1157th value should be 0");
-assertEq(view[1158], 0, "1158th value should be 0");
-assertEq(view[1159], 255, "1159th value should be 255");
-assertEq(view[1160], 0, "1160th value should be 0");
-assertEq(view[1161], 0, "1161th value should be 0");
-assertEq(view[1162], 0, "1162th value should be 0");
-assertEq(view[1163], 255, "1163th value should be 255");
-assertEq(view[1164], 0, "1164th value should be 0");
-assertEq(view[1165], 0, "1165th value should be 0");
-assertEq(view[1166], 0, "1166th value should be 0");
-assertEq(view[1167], 255, "1167th value should be 255");
-assertEq(view[1168], 0, "1168th value should be 0");
-assertEq(view[1169], 0, "1169th value should be 0");
-assertEq(view[1170], 0, "1170th value should be 0");
-assertEq(view[1171], 255, "1171th value should be 255");
-assertEq(view[1172], 0, "1172th value should be 0");
-assertEq(view[1173], 0, "1173th value should be 0");
-assertEq(view[1174], 0, "1174th value should be 0");
-assertEq(view[1175], 255, "1175th value should be 255");
-assertEq(view[1176], 0, "1176th value should be 0");
-assertEq(view[1177], 0, "1177th value should be 0");
-assertEq(view[1178], 0, "1178th value should be 0");
-assertEq(view[1179], 255, "1179th value should be 255");
-assertEq(view[1180], 0, "1180th value should be 0");
-assertEq(view[1181], 0, "1181th value should be 0");
-assertEq(view[1182], 0, "1182th value should be 0");
-assertEq(view[1183], 255, "1183th value should be 255");
-assertEq(view[1184], 26, "1184th value should be 26");
-assertEq(view[1185], 127, "1185th value should be 127");
-assertEq(view[1186], 229, "1186th value should be 229");
-assertEq(view[1187], 255, "1187th value should be 255");
-assertEq(view[1188], 154, "1188th value should be 154");
-assertEq(view[1189], 255, "1189th value should be 255");
-assertEq(view[1190], 101, "1190th value should be 101");
-assertEq(view[1191], 255, "1191th value should be 255");
-assertEq(view[1192], 205, "1192th value should be 205");
-assertEq(view[1193], 255, "1193th value should be 255");
-assertEq(view[1194], 50, "1194th value should be 50");
-assertEq(view[1195], 255, "1195th value should be 255");
-assertEq(view[1196], 205, "1196th value should be 205");
-assertEq(view[1197], 255, "1197th value should be 255");
-assertEq(view[1198], 50, "1198th value should be 50");
-assertEq(view[1199], 255, "1199th value should be 255");
-assertEq(view[1200], 230, "1200th value should be 230");
-assertEq(view[1201], 127, "1201th value should be 127");
-assertEq(view[1202], 25, "1202th value should be 25");
-assertEq(view[1203], 255, "1203th value should be 255");
-assertEq(view[1204], 205, "1204th value should be 205");
-assertEq(view[1205], 255, "1205th value should be 255");
-assertEq(view[1206], 50, "1206th value should be 50");
-assertEq(view[1207], 255, "1207th value should be 255");
-assertEq(view[1208], 205, "1208th value should be 205");
-assertEq(view[1209], 255, "1209th value should be 255");
-assertEq(view[1210], 50, "1210th value should be 50");
-assertEq(view[1211], 255, "1211th value should be 255");
-assertEq(view[1212], 205, "1212th value should be 205");
-assertEq(view[1213], 255, "1213th value should be 255");
-assertEq(view[1214], 50, "1214th value should be 50");
-assertEq(view[1215], 255, "1215th value should be 255");
-assertEq(view[1216], 205, "1216th value should be 205");
-assertEq(view[1217], 255, "1217th value should be 255");
-assertEq(view[1218], 50, "1218th value should be 50");
-assertEq(view[1219], 255, "1219th value should be 255");
-assertEq(view[1220], 154, "1220th value should be 154");
-assertEq(view[1221], 255, "1221th value should be 255");
-assertEq(view[1222], 101, "1222th value should be 101");
-assertEq(view[1223], 255, "1223th value should be 255");
-assertEq(view[1224], 154, "1224th value should be 154");
-assertEq(view[1225], 255, "1225th value should be 255");
-assertEq(view[1226], 101, "1226th value should be 101");
-assertEq(view[1227], 255, "1227th value should be 255");
-assertEq(view[1228], 154, "1228th value should be 154");
-assertEq(view[1229], 255, "1229th value should be 255");
-assertEq(view[1230], 101, "1230th value should be 101");
-assertEq(view[1231], 255, "1231th value should be 255");
-assertEq(view[1232], 128, "1232th value should be 128");
-assertEq(view[1233], 127, "1233th value should be 127");
-assertEq(view[1234], 127, "1234th value should be 127");
-assertEq(view[1235], 255, "1235th value should be 255");
-assertEq(view[1236], 26, "1236th value should be 26");
-assertEq(view[1237], 127, "1237th value should be 127");
-assertEq(view[1238], 229, "1238th value should be 229");
-assertEq(view[1239], 255, "1239th value should be 255");
-assertEq(view[1240], 0, "1240th value should be 0");
-assertEq(view[1241], 0, "1241th value should be 0");
-assertEq(view[1242], 0, "1242th value should be 0");
-assertEq(view[1243], 255, "1243th value should be 255");
-assertEq(view[1244], 0, "1244th value should be 0");
-assertEq(view[1245], 0, "1245th value should be 0");
-assertEq(view[1246], 0, "1246th value should be 0");
-assertEq(view[1247], 255, "1247th value should be 255");
-assertEq(view[1248], 0, "1248th value should be 0");
-assertEq(view[1249], 0, "1249th value should be 0");
-assertEq(view[1250], 0, "1250th value should be 0");
-assertEq(view[1251], 255, "1251th value should be 255");
-assertEq(view[1252], 0, "1252th value should be 0");
-assertEq(view[1253], 0, "1253th value should be 0");
-assertEq(view[1254], 0, "1254th value should be 0");
-assertEq(view[1255], 255, "1255th value should be 255");
-assertEq(view[1256], 0, "1256th value should be 0");
-assertEq(view[1257], 0, "1257th value should be 0");
-assertEq(view[1258], 0, "1258th value should be 0");
-assertEq(view[1259], 255, "1259th value should be 255");
-assertEq(view[1260], 0, "1260th value should be 0");
-assertEq(view[1261], 0, "1261th value should be 0");
-assertEq(view[1262], 0, "1262th value should be 0");
-assertEq(view[1263], 255, "1263th value should be 255");
-assertEq(view[1264], 78, "1264th value should be 78");
-assertEq(view[1265], 127, "1265th value should be 127");
-assertEq(view[1266], 178, "1266th value should be 178");
-assertEq(view[1267], 255, "1267th value should be 255");
-assertEq(view[1268], 179, "1268th value should be 179");
-assertEq(view[1269], 127, "1269th value should be 127");
-assertEq(view[1270], 76, "1270th value should be 76");
-assertEq(view[1271], 255, "1271th value should be 255");
-assertEq(view[1272], 205, "1272th value should be 205");
-assertEq(view[1273], 255, "1273th value should be 255");
-assertEq(view[1274], 50, "1274th value should be 50");
-assertEq(view[1275], 255, "1275th value should be 255");
-assertEq(view[1276], 205, "1276th value should be 205");
-assertEq(view[1277], 255, "1277th value should be 255");
-assertEq(view[1278], 50, "1278th value should be 50");
-assertEq(view[1279], 255, "1279th value should be 255");
-assertEq(view[1280], 0, "1280th value should be 0");
-assertEq(view[1281], 0, "1281th value should be 0");
-assertEq(view[1282], 0, "1282th value should be 0");
-assertEq(view[1283], 255, "1283th value should be 255");
-assertEq(view[1284], 205, "1284th value should be 205");
-assertEq(view[1285], 255, "1285th value should be 255");
-assertEq(view[1286], 50, "1286th value should be 50");
-assertEq(view[1287], 255, "1287th value should be 255");
-assertEq(view[1288], 205, "1288th value should be 205");
-assertEq(view[1289], 255, "1289th value should be 255");
-assertEq(view[1290], 50, "1290th value should be 50");
-assertEq(view[1291], 255, "1291th value should be 255");
-assertEq(view[1292], 205, "1292th value should be 205");
-assertEq(view[1293], 255, "1293th value should be 255");
-assertEq(view[1294], 50, "1294th value should be 50");
-assertEq(view[1295], 255, "1295th value should be 255");
-assertEq(view[1296], 205, "1296th value should be 205");
-assertEq(view[1297], 255, "1297th value should be 255");
-assertEq(view[1298], 50, "1298th value should be 50");
-assertEq(view[1299], 255, "1299th value should be 255");
-assertEq(view[1300], 205, "1300th value should be 205");
-assertEq(view[1301], 255, "1301th value should be 255");
-assertEq(view[1302], 50, "1302th value should be 50");
-assertEq(view[1303], 255, "1303th value should be 255");
-assertEq(view[1304], 179, "1304th value should be 179");
-assertEq(view[1305], 127, "1305th value should be 127");
-assertEq(view[1306], 76, "1306th value should be 76");
-assertEq(view[1307], 255, "1307th value should be 255");
-assertEq(view[1308], 154, "1308th value should be 154");
-assertEq(view[1309], 255, "1309th value should be 255");
-assertEq(view[1310], 101, "1310th value should be 101");
-assertEq(view[1311], 255, "1311th value should be 255");
-assertEq(view[1312], 154, "1312th value should be 154");
-assertEq(view[1313], 255, "1313th value should be 255");
-assertEq(view[1314], 101, "1314th value should be 101");
-assertEq(view[1315], 255, "1315th value should be 255");
-assertEq(view[1316], 0, "1316th value should be 0");
-assertEq(view[1317], 0, "1317th value should be 0");
-assertEq(view[1318], 0, "1318th value should be 0");
-assertEq(view[1319], 255, "1319th value should be 255");
-assertEq(view[1320], 0, "1320th value should be 0");
-assertEq(view[1321], 0, "1321th value should be 0");
-assertEq(view[1322], 0, "1322th value should be 0");
-assertEq(view[1323], 255, "1323th value should be 255");
-assertEq(view[1324], 0, "1324th value should be 0");
-assertEq(view[1325], 0, "1325th value should be 0");
-assertEq(view[1326], 0, "1326th value should be 0");
-assertEq(view[1327], 255, "1327th value should be 255");
-assertEq(view[1328], 0, "1328th value should be 0");
-assertEq(view[1329], 0, "1329th value should be 0");
-assertEq(view[1330], 0, "1330th value should be 0");
-assertEq(view[1331], 255, "1331th value should be 255");
-assertEq(view[1332], 0, "1332th value should be 0");
-assertEq(view[1333], 0, "1333th value should be 0");
-assertEq(view[1334], 0, "1334th value should be 0");
-assertEq(view[1335], 255, "1335th value should be 255");
-assertEq(view[1336], 0, "1336th value should be 0");
-assertEq(view[1337], 0, "1337th value should be 0");
-assertEq(view[1338], 0, "1338th value should be 0");
-assertEq(view[1339], 255, "1339th value should be 255");
-assertEq(view[1340], 0, "1340th value should be 0");
-assertEq(view[1341], 0, "1341th value should be 0");
-assertEq(view[1342], 0, "1342th value should be 0");
-assertEq(view[1343], 255, "1343th value should be 255");
-assertEq(view[1344], 0, "1344th value should be 0");
-assertEq(view[1345], 0, "1345th value should be 0");
-assertEq(view[1346], 0, "1346th value should be 0");
-assertEq(view[1347], 255, "1347th value should be 255");
-assertEq(view[1348], 179, "1348th value should be 179");
-assertEq(view[1349], 127, "1349th value should be 127");
-assertEq(view[1350], 76, "1350th value should be 76");
-assertEq(view[1351], 255, "1351th value should be 255");
-assertEq(view[1352], 205, "1352th value should be 205");
-assertEq(view[1353], 255, "1353th value should be 255");
-assertEq(view[1354], 50, "1354th value should be 50");
-assertEq(view[1355], 255, "1355th value should be 255");
-assertEq(view[1356], 205, "1356th value should be 205");
-assertEq(view[1357], 255, "1357th value should be 255");
-assertEq(view[1358], 50, "1358th value should be 50");
-assertEq(view[1359], 255, "1359th value should be 255");
-assertEq(view[1360], 0, "1360th value should be 0");
-assertEq(view[1361], 0, "1361th value should be 0");
-assertEq(view[1362], 0, "1362th value should be 0");
-assertEq(view[1363], 255, "1363th value should be 255");
-assertEq(view[1364], 205, "1364th value should be 205");
-assertEq(view[1365], 255, "1365th value should be 255");
-assertEq(view[1366], 50, "1366th value should be 50");
-assertEq(view[1367], 255, "1367th value should be 255");
-assertEq(view[1368], 205, "1368th value should be 205");
-assertEq(view[1369], 255, "1369th value should be 255");
-assertEq(view[1370], 50, "1370th value should be 50");
-assertEq(view[1371], 255, "1371th value should be 255");
-assertEq(view[1372], 205, "1372th value should be 205");
-assertEq(view[1373], 255, "1373th value should be 255");
-assertEq(view[1374], 50, "1374th value should be 50");
-assertEq(view[1375], 255, "1375th value should be 255");
-assertEq(view[1376], 205, "1376th value should be 205");
-assertEq(view[1377], 255, "1377th value should be 255");
-assertEq(view[1378], 50, "1378th value should be 50");
-assertEq(view[1379], 255, "1379th value should be 255");
-assertEq(view[1380], 205, "1380th value should be 205");
-assertEq(view[1381], 255, "1381th value should be 255");
-assertEq(view[1382], 50, "1382th value should be 50");
-assertEq(view[1383], 255, "1383th value should be 255");
-assertEq(view[1384], 205, "1384th value should be 205");
-assertEq(view[1385], 255, "1385th value should be 255");
-assertEq(view[1386], 50, "1386th value should be 50");
-assertEq(view[1387], 255, "1387th value should be 255");
-assertEq(view[1388], 179, "1388th value should be 179");
-assertEq(view[1389], 127, "1389th value should be 127");
-assertEq(view[1390], 76, "1390th value should be 76");
-assertEq(view[1391], 255, "1391th value should be 255");
-assertEq(view[1392], 179, "1392th value should be 179");
-assertEq(view[1393], 127, "1393th value should be 127");
-assertEq(view[1394], 76, "1394th value should be 76");
-assertEq(view[1395], 255, "1395th value should be 255");
-assertEq(view[1396], 103, "1396th value should be 103");
-assertEq(view[1397], 255, "1397th value should be 255");
-assertEq(view[1398], 152, "1398th value should be 152");
-assertEq(view[1399], 255, "1399th value should be 255");
-assertEq(view[1400], 78, "1400th value should be 78");
-assertEq(view[1401], 127, "1401th value should be 127");
-assertEq(view[1402], 178, "1402th value should be 178");
-assertEq(view[1403], 255, "1403th value should be 255");
-assertEq(view[1404], 52, "1404th value should be 52");
-assertEq(view[1405], 255, "1405th value should be 255");
-assertEq(view[1406], 203, "1406th value should be 203");
-assertEq(view[1407], 255, "1407th value should be 255");
-assertEq(view[1408], 0, "1408th value should be 0");
-assertEq(view[1409], 0, "1409th value should be 0");
-assertEq(view[1410], 0, "1410th value should be 0");
-assertEq(view[1411], 255, "1411th value should be 255");
-assertEq(view[1412], 0, "1412th value should be 0");
-assertEq(view[1413], 0, "1413th value should be 0");
-assertEq(view[1414], 0, "1414th value should be 0");
-assertEq(view[1415], 255, "1415th value should be 255");
-assertEq(view[1416], 52, "1416th value should be 52");
-assertEq(view[1417], 255, "1417th value should be 255");
-assertEq(view[1418], 203, "1418th value should be 203");
-assertEq(view[1419], 255, "1419th value should be 255");
-assertEq(view[1420], 128, "1420th value should be 128");
-assertEq(view[1421], 127, "1421th value should be 127");
-assertEq(view[1422], 127, "1422th value should be 127");
-assertEq(view[1423], 255, "1423th value should be 255");
-assertEq(view[1424], 128, "1424th value should be 128");
-assertEq(view[1425], 127, "1425th value should be 127");
-assertEq(view[1426], 127, "1426th value should be 127");
-assertEq(view[1427], 255, "1427th value should be 255");
-assertEq(view[1428], 205, "1428th value should be 205");
-assertEq(view[1429], 255, "1429th value should be 255");
-assertEq(view[1430], 50, "1430th value should be 50");
-assertEq(view[1431], 255, "1431th value should be 255");
-assertEq(view[1432], 205, "1432th value should be 205");
-assertEq(view[1433], 255, "1433th value should be 255");
-assertEq(view[1434], 50, "1434th value should be 50");
-assertEq(view[1435], 255, "1435th value should be 255");
-assertEq(view[1436], 230, "1436th value should be 230");
-assertEq(view[1437], 127, "1437th value should be 127");
-assertEq(view[1438], 25, "1438th value should be 25");
-assertEq(view[1439], 255, "1439th value should be 255");
-assertEq(view[1440], 0, "1440th value should be 0");
-assertEq(view[1441], 0, "1441th value should be 0");
-assertEq(view[1442], 0, "1442th value should be 0");
-assertEq(view[1443], 255, "1443th value should be 255");
-assertEq(view[1444], 230, "1444th value should be 230");
-assertEq(view[1445], 127, "1445th value should be 127");
-assertEq(view[1446], 25, "1446th value should be 25");
-assertEq(view[1447], 255, "1447th value should be 255");
-assertEq(view[1448], 205, "1448th value should be 205");
-assertEq(view[1449], 255, "1449th value should be 255");
-assertEq(view[1450], 50, "1450th value should be 50");
-assertEq(view[1451], 255, "1451th value should be 255");
-assertEq(view[1452], 205, "1452th value should be 205");
-assertEq(view[1453], 255, "1453th value should be 255");
-assertEq(view[1454], 50, "1454th value should be 50");
-assertEq(view[1455], 255, "1455th value should be 255");
-assertEq(view[1456], 205, "1456th value should be 205");
-assertEq(view[1457], 255, "1457th value should be 255");
-assertEq(view[1458], 50, "1458th value should be 50");
-assertEq(view[1459], 255, "1459th value should be 255");
-assertEq(view[1460], 205, "1460th value should be 205");
-assertEq(view[1461], 255, "1461th value should be 255");
-assertEq(view[1462], 50, "1462th value should be 50");
-assertEq(view[1463], 255, "1463th value should be 255");
-assertEq(view[1464], 205, "1464th value should be 205");
-assertEq(view[1465], 255, "1465th value should be 255");
-assertEq(view[1466], 50, "1466th value should be 50");
-assertEq(view[1467], 255, "1467th value should be 255");
-assertEq(view[1468], 179, "1468th value should be 179");
-assertEq(view[1469], 127, "1469th value should be 127");
-assertEq(view[1470], 76, "1470th value should be 76");
-assertEq(view[1471], 255, "1471th value should be 255");
-assertEq(view[1472], 179, "1472th value should be 179");
-assertEq(view[1473], 127, "1473th value should be 127");
-assertEq(view[1474], 76, "1474th value should be 76");
-assertEq(view[1475], 255, "1475th value should be 255");
-assertEq(view[1476], 179, "1476th value should be 179");
-assertEq(view[1477], 127, "1477th value should be 127");
-assertEq(view[1478], 76, "1478th value should be 76");
-assertEq(view[1479], 255, "1479th value should be 255");
-assertEq(view[1480], 128, "1480th value should be 128");
-assertEq(view[1481], 127, "1481th value should be 127");
-assertEq(view[1482], 127, "1482th value should be 127");
-assertEq(view[1483], 255, "1483th value should be 255");
-assertEq(view[1484], 103, "1484th value should be 103");
-assertEq(view[1485], 255, "1485th value should be 255");
-assertEq(view[1486], 152, "1486th value should be 152");
-assertEq(view[1487], 255, "1487th value should be 255");
-assertEq(view[1488], 0, "1488th value should be 0");
-assertEq(view[1489], 0, "1489th value should be 0");
-assertEq(view[1490], 0, "1490th value should be 0");
-assertEq(view[1491], 255, "1491th value should be 255");
-assertEq(view[1492], 0, "1492th value should be 0");
-assertEq(view[1493], 0, "1493th value should be 0");
-assertEq(view[1494], 0, "1494th value should be 0");
-assertEq(view[1495], 255, "1495th value should be 255");
-assertEq(view[1496], 128, "1496th value should be 128");
-assertEq(view[1497], 127, "1497th value should be 127");
-assertEq(view[1498], 127, "1498th value should be 127");
-assertEq(view[1499], 255, "1499th value should be 255");
-assertEq(view[1500], 154, "1500th value should be 154");
-assertEq(view[1501], 255, "1501th value should be 255");
-assertEq(view[1502], 101, "1502th value should be 101");
-assertEq(view[1503], 255, "1503th value should be 255");
-assertEq(view[1504], 179, "1504th value should be 179");
-assertEq(view[1505], 127, "1505th value should be 127");
-assertEq(view[1506], 76, "1506th value should be 76");
-assertEq(view[1507], 255, "1507th value should be 255");
-assertEq(view[1508], 205, "1508th value should be 205");
-assertEq(view[1509], 255, "1509th value should be 255");
-assertEq(view[1510], 50, "1510th value should be 50");
-assertEq(view[1511], 255, "1511th value should be 255");
-assertEq(view[1512], 205, "1512th value should be 205");
-assertEq(view[1513], 255, "1513th value should be 255");
-assertEq(view[1514], 50, "1514th value should be 50");
-assertEq(view[1515], 255, "1515th value should be 255");
-assertEq(view[1516], 230, "1516th value should be 230");
-assertEq(view[1517], 127, "1517th value should be 127");
-assertEq(view[1518], 25, "1518th value should be 25");
-assertEq(view[1519], 255, "1519th value should be 255");
-assertEq(view[1520], 0, "1520th value should be 0");
-assertEq(view[1521], 0, "1521th value should be 0");
-assertEq(view[1522], 0, "1522th value should be 0");
-assertEq(view[1523], 255, "1523th value should be 255");
-assertEq(view[1524], 230, "1524th value should be 230");
-assertEq(view[1525], 127, "1525th value should be 127");
-assertEq(view[1526], 25, "1526th value should be 25");
-assertEq(view[1527], 255, "1527th value should be 255");
-assertEq(view[1528], 230, "1528th value should be 230");
-assertEq(view[1529], 127, "1529th value should be 127");
-assertEq(view[1530], 25, "1530th value should be 25");
-assertEq(view[1531], 255, "1531th value should be 255");
-assertEq(view[1532], 205, "1532th value should be 205");
-assertEq(view[1533], 255, "1533th value should be 255");
-assertEq(view[1534], 50, "1534th value should be 50");
-assertEq(view[1535], 255, "1535th value should be 255");
-assertEq(view[1536], 205, "1536th value should be 205");
-assertEq(view[1537], 255, "1537th value should be 255");
-assertEq(view[1538], 50, "1538th value should be 50");
-assertEq(view[1539], 255, "1539th value should be 255");
-assertEq(view[1540], 205, "1540th value should be 205");
-assertEq(view[1541], 255, "1541th value should be 255");
-assertEq(view[1542], 50, "1542th value should be 50");
-assertEq(view[1543], 255, "1543th value should be 255");
-assertEq(view[1544], 205, "1544th value should be 205");
-assertEq(view[1545], 255, "1545th value should be 255");
-assertEq(view[1546], 50, "1546th value should be 50");
-assertEq(view[1547], 255, "1547th value should be 255");
-assertEq(view[1548], 205, "1548th value should be 205");
-assertEq(view[1549], 255, "1549th value should be 255");
-assertEq(view[1550], 50, "1550th value should be 50");
-assertEq(view[1551], 255, "1551th value should be 255");
-assertEq(view[1552], 179, "1552th value should be 179");
-assertEq(view[1553], 127, "1553th value should be 127");
-assertEq(view[1554], 76, "1554th value should be 76");
-assertEq(view[1555], 255, "1555th value should be 255");
-assertEq(view[1556], 179, "1556th value should be 179");
-assertEq(view[1557], 127, "1557th value should be 127");
-assertEq(view[1558], 76, "1558th value should be 76");
-assertEq(view[1559], 255, "1559th value should be 255");
-assertEq(view[1560], 179, "1560th value should be 179");
-assertEq(view[1561], 127, "1561th value should be 127");
-assertEq(view[1562], 76, "1562th value should be 76");
-assertEq(view[1563], 255, "1563th value should be 255");
-assertEq(view[1564], 154, "1564th value should be 154");
-assertEq(view[1565], 255, "1565th value should be 255");
-assertEq(view[1566], 101, "1566th value should be 101");
-assertEq(view[1567], 255, "1567th value should be 255");
-assertEq(view[1568], 26, "1568th value should be 26");
-assertEq(view[1569], 127, "1569th value should be 127");
-assertEq(view[1570], 229, "1570th value should be 229");
-assertEq(view[1571], 255, "1571th value should be 255");
-assertEq(view[1572], 0, "1572th value should be 0");
-assertEq(view[1573], 0, "1573th value should be 0");
-assertEq(view[1574], 0, "1574th value should be 0");
-assertEq(view[1575], 255, "1575th value should be 255");
-assertEq(view[1576], 154, "1576th value should be 154");
-assertEq(view[1577], 255, "1577th value should be 255");
-assertEq(view[1578], 101, "1578th value should be 101");
-assertEq(view[1579], 255, "1579th value should be 255");
-assertEq(view[1580], 179, "1580th value should be 179");
-assertEq(view[1581], 127, "1581th value should be 127");
-assertEq(view[1582], 76, "1582th value should be 76");
-assertEq(view[1583], 255, "1583th value should be 255");
-assertEq(view[1584], 205, "1584th value should be 205");
-assertEq(view[1585], 255, "1585th value should be 255");
-assertEq(view[1586], 50, "1586th value should be 50");
-assertEq(view[1587], 255, "1587th value should be 255");
-assertEq(view[1588], 205, "1588th value should be 205");
-assertEq(view[1589], 255, "1589th value should be 255");
-assertEq(view[1590], 50, "1590th value should be 50");
-assertEq(view[1591], 255, "1591th value should be 255");
-assertEq(view[1592], 230, "1592th value should be 230");
-assertEq(view[1593], 127, "1593th value should be 127");
-assertEq(view[1594], 25, "1594th value should be 25");
-assertEq(view[1595], 255, "1595th value should be 255");
-assertEq(view[1596], 230, "1596th value should be 230");
-assertEq(view[1597], 127, "1597th value should be 127");
-assertEq(view[1598], 25, "1598th value should be 25");
-assertEq(view[1599], 255, "1599th value should be 255");
-
-// Code used to generate the assertEq list above.
-function generateAssertList() {
-  function template(i, x) {
-    return 'assertEq(view[' + i + '], ' + x + ', "' + i + 'th value should be ' + x + '");\n';
-  }
-  var buf = ''
-  for (var i = 0; i < LIMIT_SHOW; i++)
-      buf += template(i, view[i]);
-  print(buf);
-}
-//generateAssertList();
+/* -*- Mode: javascript; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 ; js-indent-level : 2 ; js-curly-indent-offset: 0 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+
+// Mandelbrot using SIMD
+// Author: Peter Jensen, Intel Corporation
+
+load(libdir + "asm.js");
+if (!isSimdAvailable() || typeof SIMD === 'undefined') {
+    print("won't run tests as simd extensions aren't activated yet");
+    quit(0);
+}
+
+// global variables
+const MAX_ITERATIONS = 10;
+const DRAW_ITERATIONS = 10;
+
+const CANVAS_WIDTH = 20;
+const CANVAS_HEIGHT = 20;
+
+const LIMIT_SHOW = 20 * 20 * 4;
+
+// Asm.js module buffer.
+var buffer = new ArrayBuffer(16 * 1024 * 1024);
+var view = new Uint8Array(buffer);
+
+var moduleCode = `
+  "use asm"
+  var b8 = new global.Uint8Array(buffer);
+  var toF = global.Math.fround;
+  var i4 = global.SIMD.int32x4;
+  var ci4 = i4.check;
+  var f4 = global.SIMD.float32x4;
+  var i4add = i4.add;
+  var i4and = i4.and;
+  var f4add = f4.add;
+  var f4sub = f4.sub;
+  var f4mul = f4.mul;
+  var f4lessThanOrEqual = f4.lessThanOrEqual;
+  var f4splat = f4.splat;
+  var imul = global.Math.imul;
+  const one4 = i4(1,1,1,1), two4 = f4(2,2,2,2), four4 = f4(4,4,4,4);
+
+  const mk0 = 0x007fffff;
+
+  function declareHeapLength() {
+    b8[0x00ffffff] = 0;
+  }
+
+  function mapColorAndSetPixel (x, y, width, value, max_iterations) {
+    x = x | 0;
+    y = y | 0;
+    width = width | 0;
+    value = value | 0;
+    max_iterations = max_iterations | 0;
+
+    var rgb = 0, r = 0, g = 0, b = 0, index = 0;
+
+    index = (((imul((width >>> 0), (y >>> 0)) + x) | 0) * 4) | 0;
+    if ((value | 0) == (max_iterations | 0)) {
+      r = 0;
+      g = 0;
+      b = 0;
+    } else {
+      rgb = ~~toF(toF(toF(toF(value >>> 0) * toF(0xffff)) / toF(max_iterations >>> 0)) * toF(0xff));
+      r = rgb & 0xff;
+      g = (rgb >>> 8) & 0xff;
+      b = (rgb >>> 16) & 0xff;
+    }
+    b8[(index & mk0) >> 0] = r;
+    b8[(index & mk0) + 1 >> 0] = g;
+    b8[(index & mk0) + 2 >> 0] = b;
+    b8[(index & mk0) + 3 >> 0] = 255;
+  }
+
+  function mandelPixelX4 (xf, yf, yd, max_iterations) {
+    xf = toF(xf);
+    yf = toF(yf);
+    yd = toF(yd);
+    max_iterations = max_iterations | 0;
+    var c_re4  = f4(0,0,0,0), c_im4  = f4(0,0,0,0);
+    var z_re4  = f4(0,0,0,0), z_im4  = f4(0,0,0,0);
+    var count4 = i4(0,0,0,0);
+    var z_re24 = f4(0,0,0,0), z_im24 = f4(0,0,0,0);
+    var new_re4 = f4(0,0,0,0), new_im4 = f4(0,0,0,0);
+    var i = 0;
+    var mi4 = i4(0,0,0,0);
+
+    c_re4 = f4splat(xf);
+    c_im4 = f4(yf, toF(yd + yf), toF(yd + toF(yd + yf)), toF(yd + toF(yd + toF(yd + yf))));
+
+    z_re4  = c_re4;
+    z_im4  = c_im4;
+
+    for (i = 0; (i | 0) < (max_iterations | 0); i = (i + 1) | 0) {
+      z_re24 = f4mul(z_re4, z_re4);
+      z_im24 = f4mul(z_im4, z_im4);
+      mi4 = f4lessThanOrEqual(f4add(z_re24, z_im24), four4);
+      // If all 4 values are greater than 4.0, there's no reason to continue.
+      if ((mi4.signMask | 0) == 0x00)
+        break;
+
+      new_re4 = f4sub(z_re24, z_im24);
+      new_im4 = f4mul(f4mul(two4, z_re4), z_im4);
+      z_re4   = f4add(c_re4, new_re4);
+      z_im4   = f4add(c_im4, new_im4);
+      count4  = i4add(count4, i4and(mi4, one4));
+    }
+    return ci4(count4);
+  }
+
+  function mandelColumnX4 (x, width, height, xf, yf, yd, max_iterations) {
+    x = x | 0;
+    width = width | 0;
+    height = height | 0;
+    xf = toF(xf);
+    yf = toF(yf);
+    yd = toF(yd);
+    max_iterations = max_iterations | 0;
+
+    var y = 0;
+    var ydx4 = toF(0);
+    var m4 = i4(0,0,0,0);
+
+    ydx4 = toF(yd * toF(4));
+    for (y = 0; (y | 0) < (height | 0); y = (y + 4) | 0) {
+      m4   = ci4(mandelPixelX4(toF(xf), toF(yf), toF(yd), max_iterations));
+      mapColorAndSetPixel(x | 0, y | 0,   width, m4.x, max_iterations);
+      mapColorAndSetPixel(x | 0, (y + 1) | 0, width, m4.y, max_iterations);
+      mapColorAndSetPixel(x | 0, (y + 2) | 0, width, m4.z, max_iterations);
+      mapColorAndSetPixel(x | 0, (y + 3) | 0, width, m4.w, max_iterations);
+      yf = toF(yf + ydx4);
+    }
+  }
+
+  function mandel (width, height, xc, yc, scale, max_iterations) {
+    width = width | 0;
+    height = height | 0;
+    xc = toF(xc);
+    yc = toF(yc);
+    scale = toF(scale);
+    max_iterations = max_iterations | 0;
+
+    var x0 = toF(0), y0 = toF(0);
+    var xd = toF(0), yd = toF(0);
+    var xf = toF(0);
+    var x = 0;
+
+    x0 = toF(xc - toF(scale * toF(1.5)));
+    y0 = toF(yc - scale);
+    xd = toF(toF(scale * toF(3)) / toF(width >>> 0));
+    yd = toF(toF(scale * toF(2)) / toF(height >>> 0));
+    xf = x0;
+
+    for (x = 0; (x | 0) < (width | 0); x = (x + 1) | 0) {
+      mandelColumnX4(x, width, height, xf, y0, yd, max_iterations);
+      xf = toF(xf + xd);
+    }
+  }
+
+  return mandel;
+`;
+
+var FFI = {};
+var mandelbro = asmLink(asmCompile('global', 'ffi', 'buffer', moduleCode), this, FFI, buffer);
+
+function animateMandelbrot () {
+  var scale_start = 1.0;
+  var scale_end   = 0.0005;
+  var xc_start    = -0.5;
+  var yc_start    = 0.0;
+  var xc_end      = 0.0;
+  var yc_end      = 0.75;
+  var steps       = 200.0;
+  var scale_step  = (scale_end - scale_start)/steps;
+  var xc_step     = (xc_end - xc_start)/steps;
+  var yc_step     = (yc_end - yc_start)/steps;
+  var scale       = scale_start;
+  var xc          = xc_start;
+  var yc          = yc_start;
+  var i           = 0;
+  var now         = dateNow();
+
+  function draw1 () {
+    mandelbro(CANVAS_WIDTH, CANVAS_HEIGHT, xc, yc, scale, MAX_ITERATIONS);
+    if (scale < scale_end || scale > scale_start) {
+      scale_step = -scale_step;
+      xc_step = -xc_step;
+      yc_step = -yc_step;
+    }
+    scale += scale_step;
+    xc += xc_step;
+    yc += yc_step;
+    i++;
+  }
+
+  var b = dateNow();
+  for (var j = DRAW_ITERATIONS; j --> 0;)
+    draw1();
+  print(dateNow() - b);
+}
+
+animateMandelbrot();
+
+assertEq(view[0], 0, "0th value should be 0");
+assertEq(view[1], 0, "1th value should be 0");
+assertEq(view[2], 0, "2th value should be 0");
+assertEq(view[3], 255, "3th value should be 255");
+assertEq(view[4], 230, "4th value should be 230");
+assertEq(view[5], 127, "5th value should be 127");
+assertEq(view[6], 25, "6th value should be 25");
+assertEq(view[7], 255, "7th value should be 255");
+assertEq(view[8], 230, "8th value should be 230");
+assertEq(view[9], 127, "9th value should be 127");
+assertEq(view[10], 25, "10th value should be 25");
+assertEq(view[11], 255, "11th value should be 255");
+assertEq(view[12], 205, "12th value should be 205");
+assertEq(view[13], 255, "13th value should be 255");
+assertEq(view[14], 50, "14th value should be 50");
+assertEq(view[15], 255, "15th value should be 255");
+assertEq(view[16], 205, "16th value should be 205");
+assertEq(view[17], 255, "17th value should be 255");
+assertEq(view[18], 50, "18th value should be 50");
+assertEq(view[19], 255, "19th value should be 255");
+assertEq(view[20], 205, "20th value should be 205");
+assertEq(view[21], 255, "21th value should be 255");
+assertEq(view[22], 50, "22th value should be 50");
+assertEq(view[23], 255, "23th value should be 255");
+assertEq(view[24], 205, "24th value should be 205");
+assertEq(view[25], 255, "25th value should be 255");
+assertEq(view[26], 50, "26th value should be 50");
+assertEq(view[27], 255, "27th value should be 255");
+assertEq(view[28], 205, "28th value should be 205");
+assertEq(view[29], 255, "29th value should be 255");
+assertEq(view[30], 50, "30th value should be 50");
+assertEq(view[31], 255, "31th value should be 255");
+assertEq(view[32], 179, "32th value should be 179");
+assertEq(view[33], 127, "33th value should be 127");
+assertEq(view[34], 76, "34th value should be 76");
+assertEq(view[35], 255, "35th value should be 255");
+assertEq(view[36], 179, "36th value should be 179");
+assertEq(view[37], 127, "37th value should be 127");
+assertEq(view[38], 76, "38th value should be 76");
+assertEq(view[39], 255, "39th value should be 255");
+assertEq(view[40], 179, "40th value should be 179");
+assertEq(view[41], 127, "41th value should be 127");
+assertEq(view[42], 76, "42th value should be 76");
+assertEq(view[43], 255, "43th value should be 255");
+assertEq(view[44], 154, "44th value should be 154");
+assertEq(view[45], 255, "45th value should be 255");
+assertEq(view[46], 101, "46th value should be 101");
+assertEq(view[47], 255, "47th value should be 255");
+assertEq(view[48], 78, "48th value should be 78");
+assertEq(view[49], 127, "49th value should be 127");
+assertEq(view[50], 178, "50th value should be 178");
+assertEq(view[51], 255, "51th value should be 255");
+assertEq(view[52], 52, "52th value should be 52");
+assertEq(view[53], 255, "53th value should be 255");
+assertEq(view[54], 203, "54th value should be 203");
+assertEq(view[55], 255, "55th value should be 255");
+assertEq(view[56], 154, "56th value should be 154");
+assertEq(view[57], 255, "57th value should be 255");
+assertEq(view[58], 101, "58th value should be 101");
+assertEq(view[59], 255, "59th value should be 255");
+assertEq(view[60], 179, "60th value should be 179");
+assertEq(view[61], 127, "61th value should be 127");
+assertEq(view[62], 76, "62th value should be 76");
+assertEq(view[63], 255, "63th value should be 255");
+assertEq(view[64], 205, "64th value should be 205");
+assertEq(view[65], 255, "65th value should be 255");
+assertEq(view[66], 50, "66th value should be 50");
+assertEq(view[67], 255, "67th value should be 255");
+assertEq(view[68], 205, "68th value should be 205");
+assertEq(view[69], 255, "69th value should be 255");
+assertEq(view[70], 50, "70th value should be 50");
+assertEq(view[71], 255, "71th value should be 255");
+assertEq(view[72], 230, "72th value should be 230");
+assertEq(view[73], 127, "73th value should be 127");
+assertEq(view[74], 25, "74th value should be 25");
+assertEq(view[75], 255, "75th value should be 255");
+assertEq(view[76], 230, "76th value should be 230");
+assertEq(view[77], 127, "77th value should be 127");
+assertEq(view[78], 25, "78th value should be 25");
+assertEq(view[79], 255, "79th value should be 255");
+assertEq(view[80], 0, "80th value should be 0");
+assertEq(view[81], 0, "81th value should be 0");
+assertEq(view[82], 0, "82th value should be 0");
+assertEq(view[83], 255, "83th value should be 255");
+assertEq(view[84], 230, "84th value should be 230");
+assertEq(view[85], 127, "85th value should be 127");
+assertEq(view[86], 25, "86th value should be 25");
+assertEq(view[87], 255, "87th value should be 255");
+assertEq(view[88], 205, "88th value should be 205");
+assertEq(view[89], 255, "89th value should be 255");
+assertEq(view[90], 50, "90th value should be 50");
+assertEq(view[91], 255, "91th value should be 255");
+assertEq(view[92], 205, "92th value should be 205");
+assertEq(view[93], 255, "93th value should be 255");
+assertEq(view[94], 50, "94th value should be 50");
+assertEq(view[95], 255, "95th value should be 255");
+assertEq(view[96], 205, "96th value should be 205");
+assertEq(view[97], 255, "97th value should be 255");
+assertEq(view[98], 50, "98th value should be 50");
+assertEq(view[99], 255, "99th value should be 255");
+assertEq(view[100], 205, "100th value should be 205");
+assertEq(view[101], 255, "101th value should be 255");
+assertEq(view[102], 50, "102th value should be 50");
+assertEq(view[103], 255, "103th value should be 255");
+assertEq(view[104], 205, "104th value should be 205");
+assertEq(view[105], 255, "105th value should be 255");
+assertEq(view[106], 50, "106th value should be 50");
+assertEq(view[107], 255, "107th value should be 255");
+assertEq(view[108], 205, "108th value should be 205");
+assertEq(view[109], 255, "109th value should be 255");
+assertEq(view[110], 50, "110th value should be 50");
+assertEq(view[111], 255, "111th value should be 255");
+assertEq(view[112], 179, "112th value should be 179");
+assertEq(view[113], 127, "113th value should be 127");
+assertEq(view[114], 76, "114th value should be 76");
+assertEq(view[115], 255, "115th value should be 255");
+assertEq(view[116], 179, "116th value should be 179");
+assertEq(view[117], 127, "117th value should be 127");
+assertEq(view[118], 76, "118th value should be 76");
+assertEq(view[119], 255, "119th value should be 255");
+assertEq(view[120], 154, "120th value should be 154");
+assertEq(view[121], 255, "121th value should be 255");
+assertEq(view[122], 101, "122th value should be 101");
+assertEq(view[123], 255, "123th value should be 255");
+assertEq(view[124], 103, "124th value should be 103");
+assertEq(view[125], 255, "125th value should be 255");
+assertEq(view[126], 152, "126th value should be 152");
+assertEq(view[127], 255, "127th value should be 255");
+assertEq(view[128], 0, "128th value should be 0");
+assertEq(view[129], 0, "129th value should be 0");
+assertEq(view[130], 0, "130th value should be 0");
+assertEq(view[131], 255, "131th value should be 255");
+assertEq(view[132], 0, "132th value should be 0");
+assertEq(view[133], 0, "133th value should be 0");
+assertEq(view[134], 0, "134th value should be 0");
+assertEq(view[135], 255, "135th value should be 255");
+assertEq(view[136], 128, "136th value should be 128");
+assertEq(view[137], 127, "137th value should be 127");
+assertEq(view[138], 127, "138th value should be 127");
+assertEq(view[139], 255, "139th value should be 255");
+assertEq(view[140], 154, "140th value should be 154");
+assertEq(view[141], 255, "141th value should be 255");
+assertEq(view[142], 101, "142th value should be 101");
+assertEq(view[143], 255, "143th value should be 255");
+assertEq(view[144], 179, "144th value should be 179");
+assertEq(view[145], 127, "145th value should be 127");
+assertEq(view[146], 76, "146th value should be 76");
+assertEq(view[147], 255, "147th value should be 255");
+assertEq(view[148], 205, "148th value should be 205");
+assertEq(view[149], 255, "149th value should be 255");
+assertEq(view[150], 50, "150th value should be 50");
+assertEq(view[151], 255, "151th value should be 255");
+assertEq(view[152], 205, "152th value should be 205");
+assertEq(view[153], 255, "153th value should be 255");
+assertEq(view[154], 50, "154th value should be 50");
+assertEq(view[155], 255, "155th value should be 255");
+assertEq(view[156], 230, "156th value should be 230");
+assertEq(view[157], 127, "157th value should be 127");
+assertEq(view[158], 25, "158th value should be 25");
+assertEq(view[159], 255, "159th value should be 255");
+assertEq(view[160], 0, "160th value should be 0");
+assertEq(view[161], 0, "161th value should be 0");
+assertEq(view[162], 0, "162th value should be 0");
+assertEq(view[163], 255, "163th value should be 255");
+assertEq(view[164], 230, "164th value should be 230");
+assertEq(view[165], 127, "165th value should be 127");
+assertEq(view[166], 25, "166th value should be 25");
+assertEq(view[167], 255, "167th value should be 255");
+assertEq(view[168], 205, "168th value should be 205");
+assertEq(view[169], 255, "169th value should be 255");
+assertEq(view[170], 50, "170th value should be 50");
+assertEq(view[171], 255, "171th value should be 255");
+assertEq(view[172], 205, "172th value should be 205");
+assertEq(view[173], 255, "173th value should be 255");
+assertEq(view[174], 50, "174th value should be 50");
+assertEq(view[175], 255, "175th value should be 255");
+assertEq(view[176], 205, "176th value should be 205");
+assertEq(view[177], 255, "177th value should be 255");
+assertEq(view[178], 50, "178th value should be 50");
+assertEq(view[179], 255, "179th value should be 255");
+assertEq(view[180], 205, "180th value should be 205");
+assertEq(view[181], 255, "181th value should be 255");
+assertEq(view[182], 50, "182th value should be 50");
+assertEq(view[183], 255, "183th value should be 255");
+assertEq(view[184], 205, "184th value should be 205");
+assertEq(view[185], 255, "185th value should be 255");
+assertEq(view[186], 50, "186th value should be 50");
+assertEq(view[187], 255, "187th value should be 255");
+assertEq(view[188], 179, "188th value should be 179");
+assertEq(view[189], 127, "189th value should be 127");
+assertEq(view[190], 76, "190th value should be 76");
+assertEq(view[191], 255, "191th value should be 255");
+assertEq(view[192], 179, "192th value should be 179");
+assertEq(view[193], 127, "193th value should be 127");
+assertEq(view[194], 76, "194th value should be 76");
+assertEq(view[195], 255, "195th value should be 255");
+assertEq(view[196], 154, "196th value should be 154");
+assertEq(view[197], 255, "197th value should be 255");
+assertEq(view[198], 101, "198th value should be 101");
+assertEq(view[199], 255, "199th value should be 255");
+assertEq(view[200], 103, "200th value should be 103");
+assertEq(view[201], 255, "201th value should be 255");
+assertEq(view[202], 152, "202th value should be 152");
+assertEq(view[203], 255, "203th value should be 255");
+assertEq(view[204], 78, "204th value should be 78");
+assertEq(view[205], 127, "205th value should be 127");
+assertEq(view[206], 178, "206th value should be 178");
+assertEq(view[207], 255, "207th value should be 255");
+assertEq(view[208], 0, "208th value should be 0");
+assertEq(view[209], 0, "209th value should be 0");
+assertEq(view[210], 0, "210th value should be 0");
+assertEq(view[211], 255, "211th value should be 255");
+assertEq(view[212], 0, "212th value should be 0");
+assertEq(view[213], 0, "213th value should be 0");
+assertEq(view[214], 0, "214th value should be 0");
+assertEq(view[215], 255, "215th value should be 255");
+assertEq(view[216], 78, "216th value should be 78");
+assertEq(view[217], 127, "217th value should be 127");
+assertEq(view[218], 178, "218th value should be 178");
+assertEq(view[219], 255, "219th value should be 255");
+assertEq(view[220], 128, "220th value should be 128");
+assertEq(view[221], 127, "221th value should be 127");
+assertEq(view[222], 127, "222th value should be 127");
+assertEq(view[223], 255, "223th value should be 255");
+assertEq(view[224], 154, "224th value should be 154");
+assertEq(view[225], 255, "225th value should be 255");
+assertEq(view[226], 101, "226th value should be 101");
+assertEq(view[227], 255, "227th value should be 255");
+assertEq(view[228], 205, "228th value should be 205");
+assertEq(view[229], 255, "229th value should be 255");
+assertEq(view[230], 50, "230th value should be 50");
+assertEq(view[231], 255, "231th value should be 255");
+assertEq(view[232], 205, "232th value should be 205");
+assertEq(view[233], 255, "233th value should be 255");
+assertEq(view[234], 50, "234th value should be 50");
+assertEq(view[235], 255, "235th value should be 255");
+assertEq(view[236], 230, "236th value should be 230");
+assertEq(view[237], 127, "237th value should be 127");
+assertEq(view[238], 25, "238th value should be 25");
+assertEq(view[239], 255, "239th value should be 255");
+assertEq(view[240], 0, "240th value should be 0");
+assertEq(view[241], 0, "241th value should be 0");
+assertEq(view[242], 0, "242th value should be 0");
+assertEq(view[243], 255, "243th value should be 255");
+assertEq(view[244], 205, "244th value should be 205");
+assertEq(view[245], 255, "245th value should be 255");
+assertEq(view[246], 50, "246th value should be 50");
+assertEq(view[247], 255, "247th value should be 255");
+assertEq(view[248], 205, "248th value should be 205");
+assertEq(view[249], 255, "249th value should be 255");
+assertEq(view[250], 50, "250th value should be 50");
+assertEq(view[251], 255, "251th value should be 255");
+assertEq(view[252], 205, "252th value should be 205");
+assertEq(view[253], 255, "253th value should be 255");
+assertEq(view[254], 50, "254th value should be 50");
+assertEq(view[255], 255, "255th value should be 255");
+assertEq(view[256], 205, "256th value should be 205");
+assertEq(view[257], 255, "257th value should be 255");
+assertEq(view[258], 50, "258th value should be 50");
+assertEq(view[259], 255, "259th value should be 255");
+assertEq(view[260], 205, "260th value should be 205");
+assertEq(view[261], 255, "261th value should be 255");
+assertEq(view[262], 50, "262th value should be 50");
+assertEq(view[263], 255, "263th value should be 255");
+assertEq(view[264], 179, "264th value should be 179");
+assertEq(view[265], 127, "265th value should be 127");
+assertEq(view[266], 76, "266th value should be 76");
+assertEq(view[267], 255, "267th value should be 255");
+assertEq(view[268], 179, "268th value should be 179");
+assertEq(view[269], 127, "269th value should be 127");
+assertEq(view[270], 76, "270th value should be 76");
+assertEq(view[271], 255, "271th value should be 255");
+assertEq(view[272], 154, "272th value should be 154");
+assertEq(view[273], 255, "273th value should be 255");
+assertEq(view[274], 101, "274th value should be 101");
+assertEq(view[275], 255, "275th value should be 255");
+assertEq(view[276], 52, "276th value should be 52");
+assertEq(view[277], 255, "277th value should be 255");
+assertEq(view[278], 203, "278th value should be 203");
+assertEq(view[279], 255, "279th value should be 255");
+assertEq(view[280], 0, "280th value should be 0");
+assertEq(view[281], 0, "281th value should be 0");
+assertEq(view[282], 0, "282th value should be 0");
+assertEq(view[283], 255, "283th value should be 255");
+assertEq(view[284], 0, "284th value should be 0");
+assertEq(view[285], 0, "285th value should be 0");
+assertEq(view[286], 0, "286th value should be 0");
+assertEq(view[287], 255, "287th value should be 255");
+assertEq(view[288], 0, "288th value should be 0");
+assertEq(view[289], 0, "289th value should be 0");
+assertEq(view[290], 0, "290th value should be 0");
+assertEq(view[291], 255, "291th value should be 255");
+assertEq(view[292], 0, "292th value should be 0");
+assertEq(view[293], 0, "293th value should be 0");
+assertEq(view[294], 0, "294th value should be 0");
+assertEq(view[295], 255, "295th value should be 255");
+assertEq(view[296], 0, "296th value should be 0");
+assertEq(view[297], 0, "297th value should be 0");
+assertEq(view[298], 0, "298th value should be 0");
+assertEq(view[299], 255, "299th value should be 255");
+assertEq(view[300], 52, "300th value should be 52");
+assertEq(view[301], 255, "301th value should be 255");
+assertEq(view[302], 203, "302th value should be 203");
+assertEq(view[303], 255, "303th value should be 255");
+assertEq(view[304], 52, "304th value should be 52");
+assertEq(view[305], 255, "305th value should be 255");
+assertEq(view[306], 203, "306th value should be 203");
+assertEq(view[307], 255, "307th value should be 255");
+assertEq(view[308], 179, "308th value should be 179");
+assertEq(view[309], 127, "309th value should be 127");
+assertEq(view[310], 76, "310th value should be 76");
+assertEq(view[311], 255, "311th value should be 255");
+assertEq(view[312], 205, "312th value should be 205");
+assertEq(view[313], 255, "313th value should be 255");
+assertEq(view[314], 50, "314th value should be 50");
+assertEq(view[315], 255, "315th value should be 255");
+assertEq(view[316], 205, "316th value should be 205");
+assertEq(view[317], 255, "317th value should be 255");
+assertEq(view[318], 50, "318th value should be 50");
+assertEq(view[319], 255, "319th value should be 255");
+assertEq(view[320], 230, "320th value should be 230");
+assertEq(view[321], 127, "321th value should be 127");
+assertEq(view[322], 25, "322th value should be 25");
+assertEq(view[323], 255, "323th value should be 255");
+assertEq(view[324], 205, "324th value should be 205");
+assertEq(view[325], 255, "325th value should be 255");
+assertEq(view[326], 50, "326th value should be 50");
+assertEq(view[327], 255, "327th value should be 255");
+assertEq(view[328], 205, "328th value should be 205");
+assertEq(view[329], 255, "329th value should be 255");
+assertEq(view[330], 50, "330th value should be 50");
+assertEq(view[331], 255, "331th value should be 255");
+assertEq(view[332], 205, "332th value should be 205");
+assertEq(view[333], 255, "333th value should be 255");
+assertEq(view[334], 50, "334th value should be 50");
+assertEq(view[335], 255, "335th value should be 255");
+assertEq(view[336], 205, "336th value should be 205");
+assertEq(view[337], 255, "337th value should be 255");
+assertEq(view[338], 50, "338th value should be 50");
+assertEq(view[339], 255, "339th value should be 255");
+assertEq(view[340], 179, "340th value should be 179");
+assertEq(view[341], 127, "341th value should be 127");
+assertEq(view[342], 76, "342th value should be 76");
+assertEq(view[343], 255, "343th value should be 255");
+assertEq(view[344], 154, "344th value should be 154");
+assertEq(view[345], 255, "345th value should be 255");
+assertEq(view[346], 101, "346th value should be 101");
+assertEq(view[347], 255, "347th value should be 255");
+assertEq(view[348], 154, "348th value should be 154");
+assertEq(view[349], 255, "349th value should be 255");
+assertEq(view[350], 101, "350th value should be 101");
+assertEq(view[351], 255, "351th value should be 255");
+assertEq(view[352], 128, "352th value should be 128");
+assertEq(view[353], 127, "353th value should be 127");
+assertEq(view[354], 127, "354th value should be 127");
+assertEq(view[355], 255, "355th value should be 255");
+assertEq(view[356], 52, "356th value should be 52");
+assertEq(view[357], 255, "357th value should be 255");
+assertEq(view[358], 203, "358th value should be 203");
+assertEq(view[359], 255, "359th value should be 255");
+assertEq(view[360], 0, "360th value should be 0");
+assertEq(view[361], 0, "361th value should be 0");
+assertEq(view[362], 0, "362th value should be 0");
+assertEq(view[363], 255, "363th value should be 255");
+assertEq(view[364], 0, "364th value should be 0");
+assertEq(view[365], 0, "365th value should be 0");
+assertEq(view[366], 0, "366th value should be 0");
+assertEq(view[367], 255, "367th value should be 255");
+assertEq(view[368], 0, "368th value should be 0");
+assertEq(view[369], 0, "369th value should be 0");
+assertEq(view[370], 0, "370th value should be 0");
+assertEq(view[371], 255, "371th value should be 255");
+assertEq(view[372], 0, "372th value should be 0");
+assertEq(view[373], 0, "373th value should be 0");
+assertEq(view[374], 0, "374th value should be 0");
+assertEq(view[375], 255, "375th value should be 255");
+assertEq(view[376], 0, "376th value should be 0");
+assertEq(view[377], 0, "377th value should be 0");
+assertEq(view[378], 0, "378th value should be 0");
+assertEq(view[379], 255, "379th value should be 255");
+assertEq(view[380], 0, "380th value should be 0");
+assertEq(view[381], 0, "381th value should be 0");
+assertEq(view[382], 0, "382th value should be 0");
+assertEq(view[383], 255, "383th value should be 255");
+assertEq(view[384], 52, "384th value should be 52");
+assertEq(view[385], 255, "385th value should be 255");
+assertEq(view[386], 203, "386th value should be 203");
+assertEq(view[387], 255, "387th value should be 255");
+assertEq(view[388], 179, "388th value should be 179");
+assertEq(view[389], 127, "389th value should be 127");
+assertEq(view[390], 76, "390th value should be 76");
+assertEq(view[391], 255, "391th value should be 255");
+assertEq(view[392], 205, "392th value should be 205");
+assertEq(view[393], 255, "393th value should be 255");
+assertEq(view[394], 50, "394th value should be 50");
+assertEq(view[395], 255, "395th value should be 255");
+assertEq(view[396], 205, "396th value should be 205");
+assertEq(view[397], 255, "397th value should be 255");
+assertEq(view[398], 50, "398th value should be 50");
+assertEq(view[399], 255, "399th value should be 255");
+assertEq(view[400], 205, "400th value should be 205");
+assertEq(view[401], 255, "401th value should be 255");
+assertEq(view[402], 50, "402th value should be 50");
+assertEq(view[403], 255, "403th value should be 255");
+assertEq(view[404], 205, "404th value should be 205");
+assertEq(view[405], 255, "405th value should be 255");
+assertEq(view[406], 50, "406th value should be 50");
+assertEq(view[407], 255, "407th value should be 255");
+assertEq(view[408], 205, "408th value should be 205");
+assertEq(view[409], 255, "409th value should be 255");
+assertEq(view[410], 50, "410th value should be 50");
+assertEq(view[411], 255, "411th value should be 255");
+assertEq(view[412], 205, "412th value should be 205");
+assertEq(view[413], 255, "413th value should be 255");
+assertEq(view[414], 50, "414th value should be 50");
+assertEq(view[415], 255, "415th value should be 255");
+assertEq(view[416], 154, "416th value should be 154");
+assertEq(view[417], 255, "417th value should be 255");
+assertEq(view[418], 101, "418th value should be 101");
+assertEq(view[419], 255, "419th value should be 255");
+assertEq(view[420], 128, "420th value should be 128");
+assertEq(view[421], 127, "421th value should be 127");
+assertEq(view[422], 127, "422th value should be 127");
+assertEq(view[423], 255, "423th value should be 255");
+assertEq(view[424], 154, "424th value should be 154");
+assertEq(view[425], 255, "425th value should be 255");
+assertEq(view[426], 101, "426th value should be 101");
+assertEq(view[427], 255, "427th value should be 255");
+assertEq(view[428], 128, "428th value should be 128");
+assertEq(view[429], 127, "429th value should be 127");
+assertEq(view[430], 127, "430th value should be 127");
+assertEq(view[431], 255, "431th value should be 255");
+assertEq(view[432], 103, "432th value should be 103");
+assertEq(view[433], 255, "433th value should be 255");
+assertEq(view[434], 152, "434th value should be 152");
+assertEq(view[435], 255, "435th value should be 255");
+assertEq(view[436], 0, "436th value should be 0");
+assertEq(view[437], 0, "437th value should be 0");
+assertEq(view[438], 0, "438th value should be 0");
+assertEq(view[439], 255, "439th value should be 255");
+assertEq(view[440], 0, "440th value should be 0");
+assertEq(view[441], 0, "441th value should be 0");
+assertEq(view[442], 0, "442th value should be 0");
+assertEq(view[443], 255, "443th value should be 255");
+assertEq(view[444], 0, "444th value should be 0");
+assertEq(view[445], 0, "445th value should be 0");
+assertEq(view[446], 0, "446th value should be 0");
+assertEq(view[447], 255, "447th value should be 255");
+assertEq(view[448], 0, "448th value should be 0");
+assertEq(view[449], 0, "449th value should be 0");
+assertEq(view[450], 0, "450th value should be 0");
+assertEq(view[451], 255, "451th value should be 255");
+assertEq(view[452], 0, "452th value should be 0");
+assertEq(view[453], 0, "453th value should be 0");
+assertEq(view[454], 0, "454th value should be 0");
+assertEq(view[455], 255, "455th value should be 255");
+assertEq(view[456], 0, "456th value should be 0");
+assertEq(view[457], 0, "457th value should be 0");
+assertEq(view[458], 0, "458th value should be 0");
+assertEq(view[459], 255, "459th value should be 255");
+assertEq(view[460], 0, "460th value should be 0");
+assertEq(view[461], 0, "461th value should be 0");
+assertEq(view[462], 0, "462th value should be 0");
+assertEq(view[463], 255, "463th value should be 255");
+assertEq(view[464], 78, "464th value should be 78");
+assertEq(view[465], 127, "465th value should be 127");
+assertEq(view[466], 178, "466th value should be 178");
+assertEq(view[467], 255, "467th value should be 255");
+assertEq(view[468], 154, "468th value should be 154");
+assertEq(view[469], 255, "469th value should be 255");
+assertEq(view[470], 101, "470th value should be 101");
+assertEq(view[471], 255, "471th value should be 255");
+assertEq(view[472], 205, "472th value should be 205");
+assertEq(view[473], 255, "473th value should be 255");
+assertEq(view[474], 50, "474th value should be 50");
+assertEq(view[475], 255, "475th value should be 255");
+assertEq(view[476], 205, "476th value should be 205");
+assertEq(view[477], 255, "477th value should be 255");
+assertEq(view[478], 50, "478th value should be 50");
+assertEq(view[479], 255, "479th value should be 255");
+assertEq(view[480], 205, "480th value should be 205");
+assertEq(view[481], 255, "481th value should be 255");
+assertEq(view[482], 50, "482th value should be 50");
+assertEq(view[483], 255, "483th value should be 255");
+assertEq(view[484], 205, "484th value should be 205");
+assertEq(view[485], 255, "485th value should be 255");
+assertEq(view[486], 50, "486th value should be 50");
+assertEq(view[487], 255, "487th value should be 255");
+assertEq(view[488], 179, "488th value should be 179");
+assertEq(view[489], 127, "489th value should be 127");
+assertEq(view[490], 76, "490th value should be 76");
+assertEq(view[491], 255, "491th value should be 255");
+assertEq(view[492], 179, "492th value should be 179");
+assertEq(view[493], 127, "493th value should be 127");
+assertEq(view[494], 76, "494th value should be 76");
+assertEq(view[495], 255, "495th value should be 255");
+assertEq(view[496], 128, "496th value should be 128");
+assertEq(view[497], 127, "497th value should be 127");
+assertEq(view[498], 127, "498th value should be 127");
+assertEq(view[499], 255, "499th value should be 255");
+assertEq(view[500], 52, "500th value should be 52");
+assertEq(view[501], 255, "501th value should be 255");
+assertEq(view[502], 203, "502th value should be 203");
+assertEq(view[503], 255, "503th value should be 255");
+assertEq(view[504], 0, "504th value should be 0");
+assertEq(view[505], 0, "505th value should be 0");
+assertEq(view[506], 0, "506th value should be 0");
+assertEq(view[507], 255, "507th value should be 255");
+assertEq(view[508], 78, "508th value should be 78");
+assertEq(view[509], 127, "509th value should be 127");
+assertEq(view[510], 178, "510th value should be 178");
+assertEq(view[511], 255, "511th value should be 255");
+assertEq(view[512], 52, "512th value should be 52");
+assertEq(view[513], 255, "513th value should be 255");
+assertEq(view[514], 203, "514th value should be 203");
+assertEq(view[515], 255, "515th value should be 255");
+assertEq(view[516], 0, "516th value should be 0");
+assertEq(view[517], 0, "517th value should be 0");
+assertEq(view[518], 0, "518th value should be 0");
+assertEq(view[519], 255, "519th value should be 255");
+assertEq(view[520], 0, "520th value should be 0");
+assertEq(view[521], 0, "521th value should be 0");
+assertEq(view[522], 0, "522th value should be 0");
+assertEq(view[523], 255, "523th value should be 255");
+assertEq(view[524], 0, "524th value should be 0");
+assertEq(view[525], 0, "525th value should be 0");
+assertEq(view[526], 0, "526th value should be 0");
+assertEq(view[527], 255, "527th value should be 255");
+assertEq(view[528], 0, "528th value should be 0");
+assertEq(view[529], 0, "529th value should be 0");
+assertEq(view[530], 0, "530th value should be 0");
+assertEq(view[531], 255, "531th value should be 255");
+assertEq(view[532], 0, "532th value should be 0");
+assertEq(view[533], 0, "533th value should be 0");
+assertEq(view[534], 0, "534th value should be 0");
+assertEq(view[535], 255, "535th value should be 255");
+assertEq(view[536], 0, "536th value should be 0");
+assertEq(view[537], 0, "537th value should be 0");
+assertEq(view[538], 0, "538th value should be 0");
+assertEq(view[539], 255, "539th value should be 255");
+assertEq(view[540], 0, "540th value should be 0");
+assertEq(view[541], 0, "541th value should be 0");
+assertEq(view[542], 0, "542th value should be 0");
+assertEq(view[543], 255, "543th value should be 255");
+assertEq(view[544], 0, "544th value should be 0");
+assertEq(view[545], 0, "545th value should be 0");
+assertEq(view[546], 0, "546th value should be 0");
+assertEq(view[547], 255, "547th value should be 255");
+assertEq(view[548], 154, "548th value should be 154");
+assertEq(view[549], 255, "549th value should be 255");
+assertEq(view[550], 101, "550th value should be 101");
+assertEq(view[551], 255, "551th value should be 255");
+assertEq(view[552], 205, "552th value should be 205");
+assertEq(view[553], 255, "553th value should be 255");
+assertEq(view[554], 50, "554th value should be 50");
+assertEq(view[555], 255, "555th value should be 255");
+assertEq(view[556], 205, "556th value should be 205");
+assertEq(view[557], 255, "557th value should be 255");
+assertEq(view[558], 50, "558th value should be 50");
+assertEq(view[559], 255, "559th value should be 255");
+assertEq(view[560], 205, "560th value should be 205");
+assertEq(view[561], 255, "561th value should be 255");
+assertEq(view[562], 50, "562th value should be 50");
+assertEq(view[563], 255, "563th value should be 255");
+assertEq(view[564], 179, "564th value should be 179");
+assertEq(view[565], 127, "565th value should be 127");
+assertEq(view[566], 76, "566th value should be 76");
+assertEq(view[567], 255, "567th value should be 255");
+assertEq(view[568], 179, "568th value should be 179");
+assertEq(view[569], 127, "569th value should be 127");
+assertEq(view[570], 76, "570th value should be 76");
+assertEq(view[571], 255, "571th value should be 255");
+assertEq(view[572], 154, "572th value should be 154");
+assertEq(view[573], 255, "573th value should be 255");
+assertEq(view[574], 101, "574th value should be 101");
+assertEq(view[575], 255, "575th value should be 255");
+assertEq(view[576], 103, "576th value should be 103");
+assertEq(view[577], 255, "577th value should be 255");
+assertEq(view[578], 152, "578th value should be 152");
+assertEq(view[579], 255, "579th value should be 255");
+assertEq(view[580], 0, "580th value should be 0");
+assertEq(view[581], 0, "581th value should be 0");
+assertEq(view[582], 0, "582th value should be 0");
+assertEq(view[583], 255, "583th value should be 255");
+assertEq(view[584], 0, "584th value should be 0");
+assertEq(view[585], 0, "585th value should be 0");
+assertEq(view[586], 0, "586th value should be 0");
+assertEq(view[587], 255, "587th value should be 255");
+assertEq(view[588], 0, "588th value should be 0");
+assertEq(view[589], 0, "589th value should be 0");
+assertEq(view[590], 0, "590th value should be 0");
+assertEq(view[591], 255, "591th value should be 255");
+assertEq(view[592], 0, "592th value should be 0");
+assertEq(view[593], 0, "593th value should be 0");
+assertEq(view[594], 0, "594th value should be 0");
+assertEq(view[595], 255, "595th value should be 255");
+assertEq(view[596], 0, "596th value should be 0");
+assertEq(view[597], 0, "597th value should be 0");
+assertEq(view[598], 0, "598th value should be 0");
+assertEq(view[599], 255, "599th value should be 255");
+assertEq(view[600], 0, "600th value should be 0");
+assertEq(view[601], 0, "601th value should be 0");
+assertEq(view[602], 0, "602th value should be 0");
+assertEq(view[603], 255, "603th value should be 255");
+assertEq(view[604], 0, "604th value should be 0");
+assertEq(view[605], 0, "605th value should be 0");
+assertEq(view[606], 0, "606th value should be 0");
+assertEq(view[607], 255, "607th value should be 255");
+assertEq(view[608], 0, "608th value should be 0");
+assertEq(view[609], 0, "609th value should be 0");
+assertEq(view[610], 0, "610th value should be 0");
+assertEq(view[611], 255, "611th value should be 255");
+assertEq(view[612], 0, "612th value should be 0");
+assertEq(view[613], 0, "613th value should be 0");
+assertEq(view[614], 0, "614th value should be 0");
+assertEq(view[615], 255, "615th value should be 255");
+assertEq(view[616], 0, "616th value should be 0");
+assertEq(view[617], 0, "617th value should be 0");
+assertEq(view[618], 0, "618th value should be 0");
+assertEq(view[619], 255, "619th value should be 255");
+assertEq(view[620], 0, "620th value should be 0");
+assertEq(view[621], 0, "621th value should be 0");
+assertEq(view[622], 0, "622th value should be 0");
+assertEq(view[623], 255, "623th value should be 255");
+assertEq(view[624], 0, "624th value should be 0");
+assertEq(view[625], 0, "625th value should be 0");
+assertEq(view[626], 0, "626th value should be 0");
+assertEq(view[627], 255, "627th value should be 255");
+assertEq(view[628], 154, "628th value should be 154");
+assertEq(view[629], 255, "629th value should be 255");
+assertEq(view[630], 101, "630th value should be 101");
+assertEq(view[631], 255, "631th value should be 255");
+assertEq(view[632], 205, "632th value should be 205");
+assertEq(view[633], 255, "633th value should be 255");
+assertEq(view[634], 50, "634th value should be 50");
+assertEq(view[635], 255, "635th value should be 255");
+assertEq(view[636], 205, "636th value should be 205");
+assertEq(view[637], 255, "637th value should be 255");
+assertEq(view[638], 50, "638th value should be 50");
+assertEq(view[639], 255, "639th value should be 255");
+assertEq(view[640], 179, "640th value should be 179");
+assertEq(view[641], 127, "641th value should be 127");
+assertEq(view[642], 76, "642th value should be 76");
+assertEq(view[643], 255, "643th value should be 255");
+assertEq(view[644], 179, "644th value should be 179");
+assertEq(view[645], 127, "645th value should be 127");
+assertEq(view[646], 76, "646th value should be 76");
+assertEq(view[647], 255, "647th value should be 255");
+assertEq(view[648], 154, "648th value should be 154");
+assertEq(view[649], 255, "649th value should be 255");
+assertEq(view[650], 101, "650th value should be 101");
+assertEq(view[651], 255, "651th value should be 255");
+assertEq(view[652], 128, "652th value should be 128");
+assertEq(view[653], 127, "653th value should be 127");
+assertEq(view[654], 127, "654th value should be 127");
+assertEq(view[655], 255, "655th value should be 255");
+assertEq(view[656], 52, "656th value should be 52");
+assertEq(view[657], 255, "657th value should be 255");
+assertEq(view[658], 203, "658th value should be 203");
+assertEq(view[659], 255, "659th value should be 255");
+assertEq(view[660], 0, "660th value should be 0");
+assertEq(view[661], 0, "661th value should be 0");
+assertEq(view[662], 0, "662th value should be 0");
+assertEq(view[663], 255, "663th value should be 255");
+assertEq(view[664], 0, "664th value should be 0");
+assertEq(view[665], 0, "665th value should be 0");
+assertEq(view[666], 0, "666th value should be 0");
+assertEq(view[667], 255, "667th value should be 255");
+assertEq(view[668], 0, "668th value should be 0");
+assertEq(view[669], 0, "669th value should be 0");
+assertEq(view[670], 0, "670th value should be 0");
+assertEq(view[671], 255, "671th value should be 255");
+assertEq(view[672], 0, "672th value should be 0");
+assertEq(view[673], 0, "673th value should be 0");
+assertEq(view[674], 0, "674th value should be 0");
+assertEq(view[675], 255, "675th value should be 255");
+assertEq(view[676], 0, "676th value should be 0");
+assertEq(view[677], 0, "677th value should be 0");
+assertEq(view[678], 0, "678th value should be 0");
+assertEq(view[679], 255, "679th value should be 255");
+assertEq(view[680], 0, "680th value should be 0");
+assertEq(view[681], 0, "681th value should be 0");
+assertEq(view[682], 0, "682th value should be 0");
+assertEq(view[683], 255, "683th value should be 255");
+assertEq(view[684], 0, "684th value should be 0");
+assertEq(view[685], 0, "685th value should be 0");
+assertEq(view[686], 0, "686th value should be 0");
+assertEq(view[687], 255, "687th value should be 255");
+assertEq(view[688], 0, "688th value should be 0");
+assertEq(view[689], 0, "689th value should be 0");
+assertEq(view[690], 0, "690th value should be 0");
+assertEq(view[691], 255, "691th value should be 255");
+assertEq(view[692], 0, "692th value should be 0");
+assertEq(view[693], 0, "693th value should be 0");
+assertEq(view[694], 0, "694th value should be 0");
+assertEq(view[695], 255, "695th value should be 255");
+assertEq(view[696], 0, "696th value should be 0");
+assertEq(view[697], 0, "697th value should be 0");
+assertEq(view[698], 0, "698th value should be 0");
+assertEq(view[699], 255, "699th value should be 255");
+assertEq(view[700], 0, "700th value should be 0");
+assertEq(view[701], 0, "701th value should be 0");
+assertEq(view[702], 0, "702th value should be 0");
+assertEq(view[703], 255, "703th value should be 255");
+assertEq(view[704], 0, "704th value should be 0");
+assertEq(view[705], 0, "705th value should be 0");
+assertEq(view[706], 0, "706th value should be 0");
+assertEq(view[707], 255, "707th value should be 255");
+assertEq(view[708], 154, "708th value should be 154");
+assertEq(view[709], 255, "709th value should be 255");
+assertEq(view[710], 101, "710th value should be 101");
+assertEq(view[711], 255, "711th value should be 255");
+assertEq(view[712], 179, "712th value should be 179");
+assertEq(view[713], 127, "713th value should be 127");
+assertEq(view[714], 76, "714th value should be 76");
+assertEq(view[715], 255, "715th value should be 255");
+assertEq(view[716], 205, "716th value should be 205");
+assertEq(view[717], 255, "717th value should be 255");
+assertEq(view[718], 50, "718th value should be 50");
+assertEq(view[719], 255, "719th value should be 255");
+assertEq(view[720], 154, "720th value should be 154");
+assertEq(view[721], 255, "721th value should be 255");
+assertEq(view[722], 101, "722th value should be 101");
+assertEq(view[723], 255, "723th value should be 255");
+assertEq(view[724], 52, "724th value should be 52");
+assertEq(view[725], 255, "725th value should be 255");
+assertEq(view[726], 203, "726th value should be 203");
+assertEq(view[727], 255, "727th value should be 255");
+assertEq(view[728], 128, "728th value should be 128");
+assertEq(view[729], 127, "729th value should be 127");
+assertEq(view[730], 127, "730th value should be 127");
+assertEq(view[731], 255, "731th value should be 255");
+assertEq(view[732], 78, "732th value should be 78");
+assertEq(view[733], 127, "733th value should be 127");
+assertEq(view[734], 178, "734th value should be 178");
+assertEq(view[735], 255, "735th value should be 255");
+assertEq(view[736], 0, "736th value should be 0");
+assertEq(view[737], 0, "737th value should be 0");
+assertEq(view[738], 0, "738th value should be 0");
+assertEq(view[739], 255, "739th value should be 255");
+assertEq(view[740], 0, "740th value should be 0");
+assertEq(view[741], 0, "741th value should be 0");
+assertEq(view[742], 0, "742th value should be 0");
+assertEq(view[743], 255, "743th value should be 255");
+assertEq(view[744], 0, "744th value should be 0");
+assertEq(view[745], 0, "745th value should be 0");
+assertEq(view[746], 0, "746th value should be 0");
+assertEq(view[747], 255, "747th value should be 255");
+assertEq(view[748], 0, "748th value should be 0");
+assertEq(view[749], 0, "749th value should be 0");
+assertEq(view[750], 0, "750th value should be 0");
+assertEq(view[751], 255, "751th value should be 255");
+assertEq(view[752], 0, "752th value should be 0");
+assertEq(view[753], 0, "753th value should be 0");
+assertEq(view[754], 0, "754th value should be 0");
+assertEq(view[755], 255, "755th value should be 255");
+assertEq(view[756], 0, "756th value should be 0");
+assertEq(view[757], 0, "757th value should be 0");
+assertEq(view[758], 0, "758th value should be 0");
+assertEq(view[759], 255, "759th value should be 255");
+assertEq(view[760], 0, "760th value should be 0");
+assertEq(view[761], 0, "761th value should be 0");
+assertEq(view[762], 0, "762th value should be 0");
+assertEq(view[763], 255, "763th value should be 255");
+assertEq(view[764], 0, "764th value should be 0");
+assertEq(view[765], 0, "765th value should be 0");
+assertEq(view[766], 0, "766th value should be 0");
+assertEq(view[767], 255, "767th value should be 255");
+assertEq(view[768], 0, "768th value should be 0");
+assertEq(view[769], 0, "769th value should be 0");
+assertEq(view[770], 0, "770th value should be 0");
+assertEq(view[771], 255, "771th value should be 255");
+assertEq(view[772], 0, "772th value should be 0");
+assertEq(view[773], 0, "773th value should be 0");
+assertEq(view[774], 0, "774th value should be 0");
+assertEq(view[775], 255, "775th value should be 255");
+assertEq(view[776], 0, "776th value should be 0");
+assertEq(view[777], 0, "777th value should be 0");
+assertEq(view[778], 0, "778th value should be 0");
+assertEq(view[779], 255, "779th value should be 255");
+assertEq(view[780], 0, "780th value should be 0");
+assertEq(view[781], 0, "781th value should be 0");
+assertEq(view[782], 0, "782th value should be 0");
+assertEq(view[783], 255, "783th value should be 255");
+assertEq(view[784], 78, "784th value should be 78");
+assertEq(view[785], 127, "785th value should be 127");
+assertEq(view[786], 178, "786th value should be 178");
+assertEq(view[787], 255, "787th value should be 255");
+assertEq(view[788], 154, "788th value should be 154");
+assertEq(view[789], 255, "789th value should be 255");
+assertEq(view[790], 101, "790th value should be 101");
+assertEq(view[791], 255, "791th value should be 255");
+assertEq(view[792], 179, "792th value should be 179");
+assertEq(view[793], 127, "793th value should be 127");
+assertEq(view[794], 76, "794th value should be 76");
+assertEq(view[795], 255, "795th value should be 255");
+assertEq(view[796], 205, "796th value should be 205");
+assertEq(view[797], 255, "797th value should be 255");
+assertEq(view[798], 50, "798th value should be 50");
+assertEq(view[799], 255, "799th value should be 255");
+assertEq(view[800], 128, "800th value should be 128");
+assertEq(view[801], 127, "801th value should be 127");
+assertEq(view[802], 127, "802th value should be 127");
+assertEq(view[803], 255, "803th value should be 255");
+assertEq(view[804], 0, "804th value should be 0");
+assertEq(view[805], 0, "805th value should be 0");
+assertEq(view[806], 0, "806th value should be 0");
+assertEq(view[807], 255, "807th value should be 255");
+assertEq(view[808], 26, "808th value should be 26");
+assertEq(view[809], 127, "809th value should be 127");
+assertEq(view[810], 229, "810th value should be 229");
+assertEq(view[811], 255, "811th value should be 255");
+assertEq(view[812], 0, "812th value should be 0");
+assertEq(view[813], 0, "813th value should be 0");
+assertEq(view[814], 0, "814th value should be 0");
+assertEq(view[815], 255, "815th value should be 255");
+assertEq(view[816], 0, "816th value should be 0");
+assertEq(view[817], 0, "817th value should be 0");
+assertEq(view[818], 0, "818th value should be 0");
+assertEq(view[819], 255, "819th value should be 255");
+assertEq(view[820], 0, "820th value should be 0");
+assertEq(view[821], 0, "821th value should be 0");
+assertEq(view[822], 0, "822th value should be 0");
+assertEq(view[823], 255, "823th value should be 255");
+assertEq(view[824], 0, "824th value should be 0");
+assertEq(view[825], 0, "825th value should be 0");
+assertEq(view[826], 0, "826th value should be 0");
+assertEq(view[827], 255, "827th value should be 255");
+assertEq(view[828], 0, "828th value should be 0");
+assertEq(view[829], 0, "829th value should be 0");
+assertEq(view[830], 0, "830th value should be 0");
+assertEq(view[831], 255, "831th value should be 255");
+assertEq(view[832], 0, "832th value should be 0");
+assertEq(view[833], 0, "833th value should be 0");
+assertEq(view[834], 0, "834th value should be 0");
+assertEq(view[835], 255, "835th value should be 255");
+assertEq(view[836], 0, "836th value should be 0");
+assertEq(view[837], 0, "837th value should be 0");
+assertEq(view[838], 0, "838th value should be 0");
+assertEq(view[839], 255, "839th value should be 255");
+assertEq(view[840], 0, "840th value should be 0");
+assertEq(view[841], 0, "841th value should be 0");
+assertEq(view[842], 0, "842th value should be 0");
+assertEq(view[843], 255, "843th value should be 255");
+assertEq(view[844], 0, "844th value should be 0");
+assertEq(view[845], 0, "845th value should be 0");
+assertEq(view[846], 0, "846th value should be 0");
+assertEq(view[847], 255, "847th value should be 255");
+assertEq(view[848], 0, "848th value should be 0");
+assertEq(view[849], 0, "849th value should be 0");
+assertEq(view[850], 0, "850th value should be 0");
+assertEq(view[851], 255, "851th value should be 255");
+assertEq(view[852], 0, "852th value should be 0");
+assertEq(view[853], 0, "853th value should be 0");
+assertEq(view[854], 0, "854th value should be 0");
+assertEq(view[855], 255, "855th value should be 255");
+assertEq(view[856], 0, "856th value should be 0");
+assertEq(view[857], 0, "857th value should be 0");
+assertEq(view[858], 0, "858th value should be 0");
+assertEq(view[859], 255, "859th value should be 255");
+assertEq(view[860], 0, "860th value should be 0");
+assertEq(view[861], 0, "861th value should be 0");
+assertEq(view[862], 0, "862th value should be 0");
+assertEq(view[863], 255, "863th value should be 255");
+assertEq(view[864], 103, "864th value should be 103");
+assertEq(view[865], 255, "865th value should be 255");
+assertEq(view[866], 152, "866th value should be 152");
+assertEq(view[867], 255, "867th value should be 255");
+assertEq(view[868], 154, "868th value should be 154");
+assertEq(view[869], 255, "869th value should be 255");
+assertEq(view[870], 101, "870th value should be 101");
+assertEq(view[871], 255, "871th value should be 255");
+assertEq(view[872], 179, "872th value should be 179");
+assertEq(view[873], 127, "873th value should be 127");
+assertEq(view[874], 76, "874th value should be 76");
+assertEq(view[875], 255, "875th value should be 255");
+assertEq(view[876], 205, "876th value should be 205");
+assertEq(view[877], 255, "877th value should be 255");
+assertEq(view[878], 50, "878th value should be 50");
+assertEq(view[879], 255, "879th value should be 255");
+assertEq(view[880], 179, "880th value should be 179");
+assertEq(view[881], 127, "881th value should be 127");
+assertEq(view[882], 76, "882th value should be 76");
+assertEq(view[883], 255, "883th value should be 255");
+assertEq(view[884], 179, "884th value should be 179");
+assertEq(view[885], 127, "885th value should be 127");
+assertEq(view[886], 76, "886th value should be 76");
+assertEq(view[887], 255, "887th value should be 255");
+assertEq(view[888], 128, "888th value should be 128");
+assertEq(view[889], 127, "889th value should be 127");
+assertEq(view[890], 127, "890th value should be 127");
+assertEq(view[891], 255, "891th value should be 255");
+assertEq(view[892], 103, "892th value should be 103");
+assertEq(view[893], 255, "893th value should be 255");
+assertEq(view[894], 152, "894th value should be 152");
+assertEq(view[895], 255, "895th value should be 255");
+assertEq(view[896], 26, "896th value should be 26");
+assertEq(view[897], 127, "897th value should be 127");
+assertEq(view[898], 229, "898th value should be 229");
+assertEq(view[899], 255, "899th value should be 255");
+assertEq(view[900], 0, "900th value should be 0");
+assertEq(view[901], 0, "901th value should be 0");
+assertEq(view[902], 0, "902th value should be 0");
+assertEq(view[903], 255, "903th value should be 255");
+assertEq(view[904], 0, "904th value should be 0");
+assertEq(view[905], 0, "905th value should be 0");
+assertEq(view[906], 0, "906th value should be 0");
+assertEq(view[907], 255, "907th value should be 255");
+assertEq(view[908], 0, "908th value should be 0");
+assertEq(view[909], 0, "909th value should be 0");
+assertEq(view[910], 0, "910th value should be 0");
+assertEq(view[911], 255, "911th value should be 255");
+assertEq(view[912], 0, "912th value should be 0");
+assertEq(view[913], 0, "913th value should be 0");
+assertEq(view[914], 0, "914th value should be 0");
+assertEq(view[915], 255, "915th value should be 255");
+assertEq(view[916], 0, "916th value should be 0");
+assertEq(view[917], 0, "917th value should be 0");
+assertEq(view[918], 0, "918th value should be 0");
+assertEq(view[919], 255, "919th value should be 255");
+assertEq(view[920], 0, "920th value should be 0");
+assertEq(view[921], 0, "921th value should be 0");
+assertEq(view[922], 0, "922th value should be 0");
+assertEq(view[923], 255, "923th value should be 255");
+assertEq(view[924], 0, "924th value should be 0");
+assertEq(view[925], 0, "925th value should be 0");
+assertEq(view[926], 0, "926th value should be 0");
+assertEq(view[927], 255, "927th value should be 255");
+assertEq(view[928], 0, "928th value should be 0");
+assertEq(view[929], 0, "929th value should be 0");
+assertEq(view[930], 0, "930th value should be 0");
+assertEq(view[931], 255, "931th value should be 255");
+assertEq(view[932], 0, "932th value should be 0");
+assertEq(view[933], 0, "933th value should be 0");
+assertEq(view[934], 0, "934th value should be 0");
+assertEq(view[935], 255, "935th value should be 255");
+assertEq(view[936], 0, "936th value should be 0");
+assertEq(view[937], 0, "937th value should be 0");
+assertEq(view[938], 0, "938th value should be 0");
+assertEq(view[939], 255, "939th value should be 255");
+assertEq(view[940], 0, "940th value should be 0");
+assertEq(view[941], 0, "941th value should be 0");
+assertEq(view[942], 0, "942th value should be 0");
+assertEq(view[943], 255, "943th value should be 255");
+assertEq(view[944], 0, "944th value should be 0");
+assertEq(view[945], 0, "945th value should be 0");
+assertEq(view[946], 0, "946th value should be 0");
+assertEq(view[947], 255, "947th value should be 255");
+assertEq(view[948], 154, "948th value should be 154");
+assertEq(view[949], 255, "949th value should be 255");
+assertEq(view[950], 101, "950th value should be 101");
+assertEq(view[951], 255, "951th value should be 255");
+assertEq(view[952], 179, "952th value should be 179");
+assertEq(view[953], 127, "953th value should be 127");
+assertEq(view[954], 76, "954th value should be 76");
+assertEq(view[955], 255, "955th value should be 255");
+assertEq(view[956], 205, "956th value should be 205");
+assertEq(view[957], 255, "957th value should be 255");
+assertEq(view[958], 50, "958th value should be 50");
+assertEq(view[959], 255, "959th value should be 255");
+assertEq(view[960], 179, "960th value should be 179");
+assertEq(view[961], 127, "961th value should be 127");
+assertEq(view[962], 76, "962th value should be 76");
+assertEq(view[963], 255, "963th value should be 255");
+assertEq(view[964], 179, "964th value should be 179");
+assertEq(view[965], 127, "965th value should be 127");
+assertEq(view[966], 76, "966th value should be 76");
+assertEq(view[967], 255, "967th value should be 255");
+assertEq(view[968], 179, "968th value should be 179");
+assertEq(view[969], 127, "969th value should be 127");
+assertEq(view[970], 76, "970th value should be 76");
+assertEq(view[971], 255, "971th value should be 255");
+assertEq(view[972], 154, "972th value should be 154");
+assertEq(view[973], 255, "973th value should be 255");
+assertEq(view[974], 101, "974th value should be 101");
+assertEq(view[975], 255, "975th value should be 255");
+assertEq(view[976], 103, "976th value should be 103");
+assertEq(view[977], 255, "977th value should be 255");
+assertEq(view[978], 152, "978th value should be 152");
+assertEq(view[979], 255, "979th value should be 255");
+assertEq(view[980], 0, "980th value should be 0");
+assertEq(view[981], 0, "981th value should be 0");
+assertEq(view[982], 0, "982th value should be 0");
+assertEq(view[983], 255, "983th value should be 255");
+assertEq(view[984], 0, "984th value should be 0");
+assertEq(view[985], 0, "985th value should be 0");
+assertEq(view[986], 0, "986th value should be 0");
+assertEq(view[987], 255, "987th value should be 255");
+assertEq(view[988], 0, "988th value should be 0");
+assertEq(view[989], 0, "989th value should be 0");
+assertEq(view[990], 0, "990th value should be 0");
+assertEq(view[991], 255, "991th value should be 255");
+assertEq(view[992], 0, "992th value should be 0");
+assertEq(view[993], 0, "993th value should be 0");
+assertEq(view[994], 0, "994th value should be 0");
+assertEq(view[995], 255, "995th value should be 255");
+assertEq(view[996], 0, "996th value should be 0");
+assertEq(view[997], 0, "997th value should be 0");
+assertEq(view[998], 0, "998th value should be 0");
+assertEq(view[999], 255, "999th value should be 255");
+assertEq(view[1000], 0, "1000th value should be 0");
+assertEq(view[1001], 0, "1001th value should be 0");
+assertEq(view[1002], 0, "1002th value should be 0");
+assertEq(view[1003], 255, "1003th value should be 255");
+assertEq(view[1004], 0, "1004th value should be 0");
+assertEq(view[1005], 0, "1005th value should be 0");
+assertEq(view[1006], 0, "1006th value should be 0");
+assertEq(view[1007], 255, "1007th value should be 255");
+assertEq(view[1008], 0, "1008th value should be 0");
+assertEq(view[1009], 0, "1009th value should be 0");
+assertEq(view[1010], 0, "1010th value should be 0");
+assertEq(view[1011], 255, "1011th value should be 255");
+assertEq(view[1012], 0, "1012th value should be 0");
+assertEq(view[1013], 0, "1013th value should be 0");
+assertEq(view[1014], 0, "1014th value should be 0");
+assertEq(view[1015], 255, "1015th value should be 255");
+assertEq(view[1016], 0, "1016th value should be 0");
+assertEq(view[1017], 0, "1017th value should be 0");
+assertEq(view[1018], 0, "1018th value should be 0");
+assertEq(view[1019], 255, "1019th value should be 255");
+assertEq(view[1020], 0, "1020th value should be 0");
+assertEq(view[1021], 0, "1021th value should be 0");
+assertEq(view[1022], 0, "1022th value should be 0");
+assertEq(view[1023], 255, "1023th value should be 255");
+assertEq(view[1024], 0, "1024th value should be 0");
+assertEq(view[1025], 0, "1025th value should be 0");
+assertEq(view[1026], 0, "1026th value should be 0");
+assertEq(view[1027], 255, "1027th value should be 255");
+assertEq(view[1028], 154, "1028th value should be 154");
+assertEq(view[1029], 255, "1029th value should be 255");
+assertEq(view[1030], 101, "1030th value should be 101");
+assertEq(view[1031], 255, "1031th value should be 255");
+assertEq(view[1032], 205, "1032th value should be 205");
+assertEq(view[1033], 255, "1033th value should be 255");
+assertEq(view[1034], 50, "1034th value should be 50");
+assertEq(view[1035], 255, "1035th value should be 255");
+assertEq(view[1036], 205, "1036th value should be 205");
+assertEq(view[1037], 255, "1037th value should be 255");
+assertEq(view[1038], 50, "1038th value should be 50");
+assertEq(view[1039], 255, "1039th value should be 255");
+assertEq(view[1040], 205, "1040th value should be 205");
+assertEq(view[1041], 255, "1041th value should be 255");
+assertEq(view[1042], 50, "1042th value should be 50");
+assertEq(view[1043], 255, "1043th value should be 255");
+assertEq(view[1044], 179, "1044th value should be 179");
+assertEq(view[1045], 127, "1045th value should be 127");
+assertEq(view[1046], 76, "1046th value should be 76");
+assertEq(view[1047], 255, "1047th value should be 255");
+assertEq(view[1048], 179, "1048th value should be 179");
+assertEq(view[1049], 127, "1049th value should be 127");
+assertEq(view[1050], 76, "1050th value should be 76");
+assertEq(view[1051], 255, "1051th value should be 255");
+assertEq(view[1052], 154, "1052th value should be 154");
+assertEq(view[1053], 255, "1053th value should be 255");
+assertEq(view[1054], 101, "1054th value should be 101");
+assertEq(view[1055], 255, "1055th value should be 255");
+assertEq(view[1056], 128, "1056th value should be 128");
+assertEq(view[1057], 127, "1057th value should be 127");
+assertEq(view[1058], 127, "1058th value should be 127");
+assertEq(view[1059], 255, "1059th value should be 255");
+assertEq(view[1060], 0, "1060th value should be 0");
+assertEq(view[1061], 0, "1061th value should be 0");
+assertEq(view[1062], 0, "1062th value should be 0");
+assertEq(view[1063], 255, "1063th value should be 255");
+assertEq(view[1064], 0, "1064th value should be 0");
+assertEq(view[1065], 0, "1065th value should be 0");
+assertEq(view[1066], 0, "1066th value should be 0");
+assertEq(view[1067], 255, "1067th value should be 255");
+assertEq(view[1068], 26, "1068th value should be 26");
+assertEq(view[1069], 127, "1069th value should be 127");
+assertEq(view[1070], 229, "1070th value should be 229");
+assertEq(view[1071], 255, "1071th value should be 255");
+assertEq(view[1072], 26, "1072th value should be 26");
+assertEq(view[1073], 127, "1073th value should be 127");
+assertEq(view[1074], 229, "1074th value should be 229");
+assertEq(view[1075], 255, "1075th value should be 255");
+assertEq(view[1076], 0, "1076th value should be 0");
+assertEq(view[1077], 0, "1077th value should be 0");
+assertEq(view[1078], 0, "1078th value should be 0");
+assertEq(view[1079], 255, "1079th value should be 255");
+assertEq(view[1080], 0, "1080th value should be 0");
+assertEq(view[1081], 0, "1081th value should be 0");
+assertEq(view[1082], 0, "1082th value should be 0");
+assertEq(view[1083], 255, "1083th value should be 255");
+assertEq(view[1084], 0, "1084th value should be 0");
+assertEq(view[1085], 0, "1085th value should be 0");
+assertEq(view[1086], 0, "1086th value should be 0");
+assertEq(view[1087], 255, "1087th value should be 255");
+assertEq(view[1088], 0, "1088th value should be 0");
+assertEq(view[1089], 0, "1089th value should be 0");
+assertEq(view[1090], 0, "1090th value should be 0");
+assertEq(view[1091], 255, "1091th value should be 255");
+assertEq(view[1092], 0, "1092th value should be 0");
+assertEq(view[1093], 0, "1093th value should be 0");
+assertEq(view[1094], 0, "1094th value should be 0");
+assertEq(view[1095], 255, "1095th value should be 255");
+assertEq(view[1096], 0, "1096th value should be 0");
+assertEq(view[1097], 0, "1097th value should be 0");
+assertEq(view[1098], 0, "1098th value should be 0");
+assertEq(view[1099], 255, "1099th value should be 255");
+assertEq(view[1100], 0, "1100th value should be 0");
+assertEq(view[1101], 0, "1101th value should be 0");
+assertEq(view[1102], 0, "1102th value should be 0");
+assertEq(view[1103], 255, "1103th value should be 255");
+assertEq(view[1104], 0, "1104th value should be 0");
+assertEq(view[1105], 0, "1105th value should be 0");
+assertEq(view[1106], 0, "1106th value should be 0");
+assertEq(view[1107], 255, "1107th value should be 255");
+assertEq(view[1108], 154, "1108th value should be 154");
+assertEq(view[1109], 255, "1109th value should be 255");
+assertEq(view[1110], 101, "1110th value should be 101");
+assertEq(view[1111], 255, "1111th value should be 255");
+assertEq(view[1112], 205, "1112th value should be 205");
+assertEq(view[1113], 255, "1113th value should be 255");
+assertEq(view[1114], 50, "1114th value should be 50");
+assertEq(view[1115], 255, "1115th value should be 255");
+assertEq(view[1116], 205, "1116th value should be 205");
+assertEq(view[1117], 255, "1117th value should be 255");
+assertEq(view[1118], 50, "1118th value should be 50");
+assertEq(view[1119], 255, "1119th value should be 255");
+assertEq(view[1120], 205, "1120th value should be 205");
+assertEq(view[1121], 255, "1121th value should be 255");
+assertEq(view[1122], 50, "1122th value should be 50");
+assertEq(view[1123], 255, "1123th value should be 255");
+assertEq(view[1124], 205, "1124th value should be 205");
+assertEq(view[1125], 255, "1125th value should be 255");
+assertEq(view[1126], 50, "1126th value should be 50");
+assertEq(view[1127], 255, "1127th value should be 255");
+assertEq(view[1128], 205, "1128th value should be 205");
+assertEq(view[1129], 255, "1129th value should be 255");
+assertEq(view[1130], 50, "1130th value should be 50");
+assertEq(view[1131], 255, "1131th value should be 255");
+assertEq(view[1132], 179, "1132th value should be 179");
+assertEq(view[1133], 127, "1133th value should be 127");
+assertEq(view[1134], 76, "1134th value should be 76");
+assertEq(view[1135], 255, "1135th value should be 255");
+assertEq(view[1136], 154, "1136th value should be 154");
+assertEq(view[1137], 255, "1137th value should be 255");
+assertEq(view[1138], 101, "1138th value should be 101");
+assertEq(view[1139], 255, "1139th value should be 255");
+assertEq(view[1140], 128, "1140th value should be 128");
+assertEq(view[1141], 127, "1141th value should be 127");
+assertEq(view[1142], 127, "1142th value should be 127");
+assertEq(view[1143], 255, "1143th value should be 255");
+assertEq(view[1144], 128, "1144th value should be 128");
+assertEq(view[1145], 127, "1145th value should be 127");
+assertEq(view[1146], 127, "1146th value should be 127");
+assertEq(view[1147], 255, "1147th value should be 255");
+assertEq(view[1148], 103, "1148th value should be 103");
+assertEq(view[1149], 255, "1149th value should be 255");
+assertEq(view[1150], 152, "1150th value should be 152");
+assertEq(view[1151], 255, "1151th value should be 255");
+assertEq(view[1152], 78, "1152th value should be 78");
+assertEq(view[1153], 127, "1153th value should be 127");
+assertEq(view[1154], 178, "1154th value should be 178");
+assertEq(view[1155], 255, "1155th value should be 255");
+assertEq(view[1156], 0, "1156th value should be 0");
+assertEq(view[1157], 0, "1157th value should be 0");
+assertEq(view[1158], 0, "1158th value should be 0");
+assertEq(view[1159], 255, "1159th value should be 255");
+assertEq(view[1160], 0, "1160th value should be 0");
+assertEq(view[1161], 0, "1161th value should be 0");
+assertEq(view[1162], 0, "1162th value should be 0");
+assertEq(view[1163], 255, "1163th value should be 255");
+assertEq(view[1164], 0, "1164th value should be 0");
+assertEq(view[1165], 0, "1165th value should be 0");
+assertEq(view[1166], 0, "1166th value should be 0");
+assertEq(view[1167], 255, "1167th value should be 255");
+assertEq(view[1168], 0, "1168th value should be 0");
+assertEq(view[1169], 0, "1169th value should be 0");
+assertEq(view[1170], 0, "1170th value should be 0");
+assertEq(view[1171], 255, "1171th value should be 255");
+assertEq(view[1172], 0, "1172th value should be 0");
+assertEq(view[1173], 0, "1173th value should be 0");
+assertEq(view[1174], 0, "1174th value should be 0");
+assertEq(view[1175], 255, "1175th value should be 255");
+assertEq(view[1176], 0, "1176th value should be 0");
+assertEq(view[1177], 0, "1177th value should be 0");
+assertEq(view[1178], 0, "1178th value should be 0");
+assertEq(view[1179], 255, "1179th value should be 255");
+assertEq(view[1180], 0, "1180th value should be 0");
+assertEq(view[1181], 0, "1181th value should be 0");
+assertEq(view[1182], 0, "1182th value should be 0");
+assertEq(view[1183], 255, "1183th value should be 255");
+assertEq(view[1184], 26, "1184th value should be 26");
+assertEq(view[1185], 127, "1185th value should be 127");
+assertEq(view[1186], 229, "1186th value should be 229");
+assertEq(view[1187], 255, "1187th value should be 255");
+assertEq(view[1188], 154, "1188th value should be 154");
+assertEq(view[1189], 255, "1189th value should be 255");
+assertEq(view[1190], 101, "1190th value should be 101");
+assertEq(view[1191], 255, "1191th value should be 255");
+assertEq(view[1192], 205, "1192th value should be 205");
+assertEq(view[1193], 255, "1193th value should be 255");
+assertEq(view[1194], 50, "1194th value should be 50");
+assertEq(view[1195], 255, "1195th value should be 255");
+assertEq(view[1196], 205, "1196th value should be 205");
+assertEq(view[1197], 255, "1197th value should be 255");
+assertEq(view[1198], 50, "1198th value should be 50");
+assertEq(view[1199], 255, "1199th value should be 255");
+assertEq(view[1200], 230, "1200th value should be 230");
+assertEq(view[1201], 127, "1201th value should be 127");
+assertEq(view[1202], 25, "1202th value should be 25");
+assertEq(view[1203], 255, "1203th value should be 255");
+assertEq(view[1204], 205, "1204th value should be 205");
+assertEq(view[1205], 255, "1205th value should be 255");
+assertEq(view[1206], 50, "1206th value should be 50");
+assertEq(view[1207], 255, "1207th value should be 255");
+assertEq(view[1208], 205, "1208th value should be 205");
+assertEq(view[1209], 255, "1209th value should be 255");
+assertEq(view[1210], 50, "1210th value should be 50");
+assertEq(view[1211], 255, "1211th value should be 255");
+assertEq(view[1212], 205, "1212th value should be 205");
+assertEq(view[1213], 255, "1213th value should be 255");
+assertEq(view[1214], 50, "1214th value should be 50");
+assertEq(view[1215], 255, "1215th value should be 255");
+assertEq(view[1216], 205, "1216th value should be 205");
+assertEq(view[1217], 255, "1217th value should be 255");
+assertEq(view[1218], 50, "1218th value should be 50");
+assertEq(view[1219], 255, "1219th value should be 255");
+assertEq(view[1220], 154, "1220th value should be 154");
+assertEq(view[1221], 255, "1221th value should be 255");
+assertEq(view[1222], 101, "1222th value should be 101");
+assertEq(view[1223], 255, "1223th value should be 255");
+assertEq(view[1224], 154, "1224th value should be 154");
+assertEq(view[1225], 255, "1225th value should be 255");
+assertEq(view[1226], 101, "1226th value should be 101");
+assertEq(view[1227], 255, "1227th value should be 255");
+assertEq(view[1228], 154, "1228th value should be 154");
+assertEq(view[1229], 255, "1229th value should be 255");
+assertEq(view[1230], 101, "1230th value should be 101");
+assertEq(view[1231], 255, "1231th value should be 255");
+assertEq(view[1232], 128, "1232th value should be 128");
+assertEq(view[1233], 127, "1233th value should be 127");
+assertEq(view[1234], 127, "1234th value should be 127");
+assertEq(view[1235], 255, "1235th value should be 255");
+assertEq(view[1236], 26, "1236th value should be 26");
+assertEq(view[1237], 127, "1237th value should be 127");
+assertEq(view[1238], 229, "1238th value should be 229");
+assertEq(view[1239], 255, "1239th value should be 255");
+assertEq(view[1240], 0, "1240th value should be 0");
+assertEq(view[1241], 0, "1241th value should be 0");
+assertEq(view[1242], 0, "1242th value should be 0");
+assertEq(view[1243], 255, "1243th value should be 255");
+assertEq(view[1244], 0, "1244th value should be 0");
+assertEq(view[1245], 0, "1245th value should be 0");
+assertEq(view[1246], 0, "1246th value should be 0");
+assertEq(view[1247], 255, "1247th value should be 255");
+assertEq(view[1248], 0, "1248th value should be 0");
+assertEq(view[1249], 0, "1249th value should be 0");
+assertEq(view[1250], 0, "1250th value should be 0");
+assertEq(view[1251], 255, "1251th value should be 255");
+assertEq(view[1252], 0, "1252th value should be 0");
+assertEq(view[1253], 0, "1253th value should be 0");
+assertEq(view[1254], 0, "1254th value should be 0");
+assertEq(view[1255], 255, "1255th value should be 255");
+assertEq(view[1256], 0, "1256th value should be 0");
+assertEq(view[1257], 0, "1257th value should be 0");
+assertEq(view[1258], 0, "1258th value should be 0");
+assertEq(view[1259], 255, "1259th value should be 255");
+assertEq(view[1260], 0, "1260th value should be 0");
+assertEq(view[1261], 0, "1261th value should be 0");
+assertEq(view[1262], 0, "1262th value should be 0");
+assertEq(view[1263], 255, "1263th value should be 255");
+assertEq(view[1264], 78, "1264th value should be 78");
+assertEq(view[1265], 127, "1265th value should be 127");
+assertEq(view[1266], 178, "1266th value should be 178");
+assertEq(view[1267], 255, "1267th value should be 255");
+assertEq(view[1268], 179, "1268th value should be 179");
+assertEq(view[1269], 127, "1269th value should be 127");
+assertEq(view[1270], 76, "1270th value should be 76");
+assertEq(view[1271], 255, "1271th value should be 255");
+assertEq(view[1272], 205, "1272th value should be 205");
+assertEq(view[1273], 255, "1273th value should be 255");
+assertEq(view[1274], 50, "1274th value should be 50");
+assertEq(view[1275], 255, "1275th value should be 255");
+assertEq(view[1276], 205, "1276th value should be 205");
+assertEq(view[1277], 255, "1277th value should be 255");
+assertEq(view[1278], 50, "1278th value should be 50");
+assertEq(view[1279], 255, "1279th value should be 255");
+assertEq(view[1280], 0, "1280th value should be 0");
+assertEq(view[1281], 0, "1281th value should be 0");
+assertEq(view[1282], 0, "1282th value should be 0");
+assertEq(view[1283], 255, "1283th value should be 255");
+assertEq(view[1284], 205, "1284th value should be 205");
+assertEq(view[1285], 255, "1285th value should be 255");
+assertEq(view[1286], 50, "1286th value should be 50");
+assertEq(view[1287], 255, "1287th value should be 255");
+assertEq(view[1288], 205, "1288th value should be 205");
+assertEq(view[1289], 255, "1289th value should be 255");
+assertEq(view[1290], 50, "1290th value should be 50");
+assertEq(view[1291], 255, "1291th value should be 255");
+assertEq(view[1292], 205, "1292th value should be 205");
+assertEq(view[1293], 255, "1293th value should be 255");
+assertEq(view[1294], 50, "1294th value should be 50");
+assertEq(view[1295], 255, "1295th value should be 255");
+assertEq(view[1296], 205, "1296th value should be 205");
+assertEq(view[1297], 255, "1297th value should be 255");
+assertEq(view[1298], 50, "1298th value should be 50");
+assertEq(view[1299], 255, "1299th value should be 255");
+assertEq(view[1300], 205, "1300th value should be 205");
+assertEq(view[1301], 255, "1301th value should be 255");
+assertEq(view[1302], 50, "1302th value should be 50");
+assertEq(view[1303], 255, "1303th value should be 255");
+assertEq(view[1304], 179, "1304th value should be 179");
+assertEq(view[1305], 127, "1305th value should be 127");
+assertEq(view[1306], 76, "1306th value should be 76");
+assertEq(view[1307], 255, "1307th value should be 255");
+assertEq(view[1308], 154, "1308th value should be 154");
+assertEq(view[1309], 255, "1309th value should be 255");
+assertEq(view[1310], 101, "1310th value should be 101");
+assertEq(view[1311], 255, "1311th value should be 255");
+assertEq(view[1312], 154, "1312th value should be 154");
+assertEq(view[1313], 255, "1313th value should be 255");
+assertEq(view[1314], 101, "1314th value should be 101");
+assertEq(view[1315], 255, "1315th value should be 255");
+assertEq(view[1316], 0, "1316th value should be 0");
+assertEq(view[1317], 0, "1317th value should be 0");
+assertEq(view[1318], 0, "1318th value should be 0");
+assertEq(view[1319], 255, "1319th value should be 255");
+assertEq(view[1320], 0, "1320th value should be 0");
+assertEq(view[1321], 0, "1321th value should be 0");
+assertEq(view[1322], 0, "1322th value should be 0");
+assertEq(view[1323], 255, "1323th value should be 255");
+assertEq(view[1324], 0, "1324th value should be 0");
+assertEq(view[1325], 0, "1325th value should be 0");
+assertEq(view[1326], 0, "1326th value should be 0");
+assertEq(view[1327], 255, "1327th value should be 255");
+assertEq(view[1328], 0, "1328th value should be 0");
+assertEq(view[1329], 0, "1329th value should be 0");
+assertEq(view[1330], 0, "1330th value should be 0");
+assertEq(view[1331], 255, "1331th value should be 255");
+assertEq(view[1332], 0, "1332th value should be 0");
+assertEq(view[1333], 0, "1333th value should be 0");
+assertEq(view[1334], 0, "1334th value should be 0");
+assertEq(view[1335], 255, "1335th value should be 255");
+assertEq(view[1336], 0, "1336th value should be 0");
+assertEq(view[1337], 0, "1337th value should be 0");
+assertEq(view[1338], 0, "1338th value should be 0");
+assertEq(view[1339], 255, "1339th value should be 255");
+assertEq(view[1340], 0, "1340th value should be 0");
+assertEq(view[1341], 0, "1341th value should be 0");
+assertEq(view[1342], 0, "1342th value should be 0");
+assertEq(view[1343], 255, "1343th value should be 255");
+assertEq(view[1344], 0, "1344th value should be 0");
+assertEq(view[1345], 0, "1345th value should be 0");
+assertEq(view[1346], 0, "1346th value should be 0");
+assertEq(view[1347], 255, "1347th value should be 255");
+assertEq(view[1348], 179, "1348th value should be 179");
+assertEq(view[1349], 127, "1349th value should be 127");
+assertEq(view[1350], 76, "1350th value should be 76");
+assertEq(view[1351], 255, "1351th value should be 255");
+assertEq(view[1352], 205, "1352th value should be 205");
+assertEq(view[1353], 255, "1353th value should be 255");
+assertEq(view[1354], 50, "1354th value should be 50");
+assertEq(view[1355], 255, "1355th value should be 255");
+assertEq(view[1356], 205, "1356th value should be 205");
+assertEq(view[1357], 255, "1357th value should be 255");
+assertEq(view[1358], 50, "1358th value should be 50");
+assertEq(view[1359], 255, "1359th value should be 255");
+assertEq(view[1360], 0, "1360th value should be 0");
+assertEq(view[1361], 0, "1361th value should be 0");
+assertEq(view[1362], 0, "1362th value should be 0");
+assertEq(view[1363], 255, "1363th value should be 255");
+assertEq(view[1364], 205, "1364th value should be 205");
+assertEq(view[1365], 255, "1365th value should be 255");
+assertEq(view[1366], 50, "1366th value should be 50");
+assertEq(view[1367], 255, "1367th value should be 255");
+assertEq(view[1368], 205, "1368th value should be 205");
+assertEq(view[1369], 255, "1369th value should be 255");
+assertEq(view[1370], 50, "1370th value should be 50");
+assertEq(view[1371], 255, "1371th value should be 255");
+assertEq(view[1372], 205, "1372th value should be 205");
+assertEq(view[1373], 255, "1373th value should be 255");
+assertEq(view[1374], 50, "1374th value should be 50");
+assertEq(view[1375], 255, "1375th value should be 255");
+assertEq(view[1376], 205, "1376th value should be 205");
+assertEq(view[1377], 255, "1377th value should be 255");
+assertEq(view[1378], 50, "1378th value should be 50");
+assertEq(view[1379], 255, "1379th value should be 255");
+assertEq(view[1380], 205, "1380th value should be 205");
+assertEq(view[1381], 255, "1381th value should be 255");
+assertEq(view[1382], 50, "1382th value should be 50");
+assertEq(view[1383], 255, "1383th value should be 255");
+assertEq(view[1384], 205, "1384th value should be 205");
+assertEq(view[1385], 255, "1385th value should be 255");
+assertEq(view[1386], 50, "1386th value should be 50");
+assertEq(view[1387], 255, "1387th value should be 255");
+assertEq(view[1388], 179, "1388th value should be 179");
+assertEq(view[1389], 127, "1389th value should be 127");
+assertEq(view[1390], 76, "1390th value should be 76");
+assertEq(view[1391], 255, "1391th value should be 255");
+assertEq(view[1392], 179, "1392th value should be 179");
+assertEq(view[1393], 127, "1393th value should be 127");
+assertEq(view[1394], 76, "1394th value should be 76");
+assertEq(view[1395], 255, "1395th value should be 255");
+assertEq(view[1396], 103, "1396th value should be 103");
+assertEq(view[1397], 255, "1397th value should be 255");
+assertEq(view[1398], 152, "1398th value should be 152");
+assertEq(view[1399], 255, "1399th value should be 255");
+assertEq(view[1400], 78, "1400th value should be 78");
+assertEq(view[1401], 127, "1401th value should be 127");
+assertEq(view[1402], 178, "1402th value should be 178");
+assertEq(view[1403], 255, "1403th value should be 255");
+assertEq(view[1404], 52, "1404th value should be 52");
+assertEq(view[1405], 255, "1405th value should be 255");
+assertEq(view[1406], 203, "1406th value should be 203");
+assertEq(view[1407], 255, "1407th value should be 255");
+assertEq(view[1408], 0, "1408th value should be 0");
+assertEq(view[1409], 0, "1409th value should be 0");
+assertEq(view[1410], 0, "1410th value should be 0");
+assertEq(view[1411], 255, "1411th value should be 255");
+assertEq(view[1412], 0, "1412th value should be 0");
+assertEq(view[1413], 0, "1413th value should be 0");
+assertEq(view[1414], 0, "1414th value should be 0");
+assertEq(view[1415], 255, "1415th value should be 255");
+assertEq(view[1416], 52, "1416th value should be 52");
+assertEq(view[1417], 255, "1417th value should be 255");
+assertEq(view[1418], 203, "1418th value should be 203");
+assertEq(view[1419], 255, "1419th value should be 255");
+assertEq(view[1420], 128, "1420th value should be 128");
+assertEq(view[1421], 127, "1421th value should be 127");
+assertEq(view[1422], 127, "1422th value should be 127");
+assertEq(view[1423], 255, "1423th value should be 255");
+assertEq(view[1424], 128, "1424th value should be 128");
+assertEq(view[1425], 127, "1425th value should be 127");
+assertEq(view[1426], 127, "1426th value should be 127");
+assertEq(view[1427], 255, "1427th value should be 255");
+assertEq(view[1428], 205, "1428th value should be 205");
+assertEq(view[1429], 255, "1429th value should be 255");
+assertEq(view[1430], 50, "1430th value should be 50");
+assertEq(view[1431], 255, "1431th value should be 255");
+assertEq(view[1432], 205, "1432th value should be 205");
+assertEq(view[1433], 255, "1433th value should be 255");
+assertEq(view[1434], 50, "1434th value should be 50");
+assertEq(view[1435], 255, "1435th value should be 255");
+assertEq(view[1436], 230, "1436th value should be 230");
+assertEq(view[1437], 127, "1437th value should be 127");
+assertEq(view[1438], 25, "1438th value should be 25");
+assertEq(view[1439], 255, "1439th value should be 255");
+assertEq(view[1440], 0, "1440th value should be 0");
+assertEq(view[1441], 0, "1441th value should be 0");
+assertEq(view[1442], 0, "1442th value should be 0");
+assertEq(view[1443], 255, "1443th value should be 255");
+assertEq(view[1444], 230, "1444th value should be 230");
+assertEq(view[1445], 127, "1445th value should be 127");
+assertEq(view[1446], 25, "1446th value should be 25");
+assertEq(view[1447], 255, "1447th value should be 255");
+assertEq(view[1448], 205, "1448th value should be 205");
+assertEq(view[1449], 255, "1449th value should be 255");
+assertEq(view[1450], 50, "1450th value should be 50");
+assertEq(view[1451], 255, "1451th value should be 255");
+assertEq(view[1452], 205, "1452th value should be 205");
+assertEq(view[1453], 255, "1453th value should be 255");
+assertEq(view[1454], 50, "1454th value should be 50");
+assertEq(view[1455], 255, "1455th value should be 255");
+assertEq(view[1456], 205, "1456th value should be 205");
+assertEq(view[1457], 255, "1457th value should be 255");
+assertEq(view[1458], 50, "1458th value should be 50");
+assertEq(view[1459], 255, "1459th value should be 255");
+assertEq(view[1460], 205, "1460th value should be 205");
+assertEq(view[1461], 255, "1461th value should be 255");
+assertEq(view[1462], 50, "1462th value should be 50");
+assertEq(view[1463], 255, "1463th value should be 255");
+assertEq(view[1464], 205, "1464th value should be 205");
+assertEq(view[1465], 255, "1465th value should be 255");
+assertEq(view[1466], 50, "1466th value should be 50");
+assertEq(view[1467], 255, "1467th value should be 255");
+assertEq(view[1468], 179, "1468th value should be 179");
+assertEq(view[1469], 127, "1469th value should be 127");
+assertEq(view[1470], 76, "1470th value should be 76");
+assertEq(view[1471], 255, "1471th value should be 255");
+assertEq(view[1472], 179, "1472th value should be 179");
+assertEq(view[1473], 127, "1473th value should be 127");
+assertEq(view[1474], 76, "1474th value should be 76");
+assertEq(view[1475], 255, "1475th value should be 255");
+assertEq(view[1476], 179, "1476th value should be 179");
+assertEq(view[1477], 127, "1477th value should be 127");
+assertEq(view[1478], 76, "1478th value should be 76");
+assertEq(view[1479], 255, "1479th value should be 255");
+assertEq(view[1480], 128, "1480th value should be 128");
+assertEq(view[1481], 127, "1481th value should be 127");
+assertEq(view[1482], 127, "1482th value should be 127");
+assertEq(view[1483], 255, "1483th value should be 255");
+assertEq(view[1484], 103, "1484th value should be 103");
+assertEq(view[1485], 255, "1485th value should be 255");
+assertEq(view[1486], 152, "1486th value should be 152");
+assertEq(view[1487], 255, "1487th value should be 255");
+assertEq(view[1488], 0, "1488th value should be 0");
+assertEq(view[1489], 0, "1489th value should be 0");
+assertEq(view[1490], 0, "1490th value should be 0");
+assertEq(view[1491], 255, "1491th value should be 255");
+assertEq(view[1492], 0, "1492th value should be 0");
+assertEq(view[1493], 0, "1493th value should be 0");
+assertEq(view[1494], 0, "1494th value should be 0");
+assertEq(view[1495], 255, "1495th value should be 255");
+assertEq(view[1496], 128, "1496th value should be 128");
+assertEq(view[1497], 127, "1497th value should be 127");
+assertEq(view[1498], 127, "1498th value should be 127");
+assertEq(view[1499], 255, "1499th value should be 255");
+assertEq(view[1500], 154, "1500th value should be 154");
+assertEq(view[1501], 255, "1501th value should be 255");
+assertEq(view[1502], 101, "1502th value should be 101");
+assertEq(view[1503], 255, "1503th value should be 255");
+assertEq(view[1504], 179, "1504th value should be 179");
+assertEq(view[1505], 127, "1505th value should be 127");
+assertEq(view[1506], 76, "1506th value should be 76");
+assertEq(view[1507], 255, "1507th value should be 255");
+assertEq(view[1508], 205, "1508th value should be 205");
+assertEq(view[1509], 255, "1509th value should be 255");
+assertEq(view[1510], 50, "1510th value should be 50");
+assertEq(view[1511], 255, "1511th value should be 255");
+assertEq(view[1512], 205, "1512th value should be 205");
+assertEq(view[1513], 255, "1513th value should be 255");
+assertEq(view[1514], 50, "1514th value should be 50");
+assertEq(view[1515], 255, "1515th value should be 255");
+assertEq(view[1516], 230, "1516th value should be 230");
+assertEq(view[1517], 127, "1517th value should be 127");
+assertEq(view[1518], 25, "1518th value should be 25");
+assertEq(view[1519], 255, "1519th value should be 255");
+assertEq(view[1520], 0, "1520th value should be 0");
+assertEq(view[1521], 0, "1521th value should be 0");
+assertEq(view[1522], 0, "1522th value should be 0");
+assertEq(view[1523], 255, "1523th value should be 255");
+assertEq(view[1524], 230, "1524th value should be 230");
+assertEq(view[1525], 127, "1525th value should be 127");
+assertEq(view[1526], 25, "1526th value should be 25");
+assertEq(view[1527], 255, "1527th value should be 255");
+assertEq(view[1528], 230, "1528th value should be 230");
+assertEq(view[1529], 127, "1529th value should be 127");
+assertEq(view[1530], 25, "1530th value should be 25");
+assertEq(view[1531], 255, "1531th value should be 255");
+assertEq(view[1532], 205, "1532th value should be 205");
+assertEq(view[1533], 255, "1533th value should be 255");
+assertEq(view[1534], 50, "1534th value should be 50");
+assertEq(view[1535], 255, "1535th value should be 255");
+assertEq(view[1536], 205, "1536th value should be 205");
+assertEq(view[1537], 255, "1537th value should be 255");
+assertEq(view[1538], 50, "1538th value should be 50");
+assertEq(view[1539], 255, "1539th value should be 255");
+assertEq(view[1540], 205, "1540th value should be 205");
+assertEq(view[1541], 255, "1541th value should be 255");
+assertEq(view[1542], 50, "1542th value should be 50");
+assertEq(view[1543], 255, "1543th value should be 255");
+assertEq(view[1544], 205, "1544th value should be 205");
+assertEq(view[1545], 255, "1545th value should be 255");
+assertEq(view[1546], 50, "1546th value should be 50");
+assertEq(view[1547], 255, "1547th value should be 255");
+assertEq(view[1548], 205, "1548th value should be 205");
+assertEq(view[1549], 255, "1549th value should be 255");
+assertEq(view[1550], 50, "1550th value should be 50");
+assertEq(view[1551], 255, "1551th value should be 255");
+assertEq(view[1552], 179, "1552th value should be 179");
+assertEq(view[1553], 127, "1553th value should be 127");
+assertEq(view[1554], 76, "1554th value should be 76");
+assertEq(view[1555], 255, "1555th value should be 255");
+assertEq(view[1556], 179, "1556th value should be 179");
+assertEq(view[1557], 127, "1557th value should be 127");
+assertEq(view[1558], 76, "1558th value should be 76");
+assertEq(view[1559], 255, "1559th value should be 255");
+assertEq(view[1560], 179, "1560th value should be 179");
+assertEq(view[1561], 127, "1561th value should be 127");
+assertEq(view[1562], 76, "1562th value should be 76");
+assertEq(view[1563], 255, "1563th value should be 255");
+assertEq(view[1564], 154, "1564th value should be 154");
+assertEq(view[1565], 255, "1565th value should be 255");
+assertEq(view[1566], 101, "1566th value should be 101");
+assertEq(view[1567], 255, "1567th value should be 255");
+assertEq(view[1568], 26, "1568th value should be 26");
+assertEq(view[1569], 127, "1569th value should be 127");
+assertEq(view[1570], 229, "1570th value should be 229");
+assertEq(view[1571], 255, "1571th value should be 255");
+assertEq(view[1572], 0, "1572th value should be 0");
+assertEq(view[1573], 0, "1573th value should be 0");
+assertEq(view[1574], 0, "1574th value should be 0");
+assertEq(view[1575], 255, "1575th value should be 255");
+assertEq(view[1576], 154, "1576th value should be 154");
+assertEq(view[1577], 255, "1577th value should be 255");
+assertEq(view[1578], 101, "1578th value should be 101");
+assertEq(view[1579], 255, "1579th value should be 255");
+assertEq(view[1580], 179, "1580th value should be 179");
+assertEq(view[1581], 127, "1581th value should be 127");
+assertEq(view[1582], 76, "1582th value should be 76");
+assertEq(view[1583], 255, "1583th value should be 255");
+assertEq(view[1584], 205, "1584th value should be 205");
+assertEq(view[1585], 255, "1585th value should be 255");
+assertEq(view[1586], 50, "1586th value should be 50");
+assertEq(view[1587], 255, "1587th value should be 255");
+assertEq(view[1588], 205, "1588th value should be 205");
+assertEq(view[1589], 255, "1589th value should be 255");
+assertEq(view[1590], 50, "1590th value should be 50");
+assertEq(view[1591], 255, "1591th value should be 255");
+assertEq(view[1592], 230, "1592th value should be 230");
+assertEq(view[1593], 127, "1593th value should be 127");
+assertEq(view[1594], 25, "1594th value should be 25");
+assertEq(view[1595], 255, "1595th value should be 255");
+assertEq(view[1596], 230, "1596th value should be 230");
+assertEq(view[1597], 127, "1597th value should be 127");
+assertEq(view[1598], 25, "1598th value should be 25");
+assertEq(view[1599], 255, "1599th value should be 255");
+
+// Code used to generate the assertEq list above.
+function generateAssertList() {
+  function template(i, x) {
+    return 'assertEq(view[' + i + '], ' + x + ', "' + i + 'th value should be ' + x + '");\n';
+  }
+  var buf = ''
+  for (var i = 0; i < LIMIT_SHOW; i++)
+      buf += template(i, view[i]);
+  print(buf);
+}
+//generateAssertList();
--- a/js/src/jit-test/tests/asm.js/testSIMD-load-store.js
+++ b/js/src/jit-test/tests/asm.js/testSIMD-load-store.js
@@ -23,18 +23,20 @@ function assertEqX4(real, expected, asse
         assertFunc(real.z, expected[2]);
         assertFunc(real.w, expected[3]);
     } catch (e) {
         print("Stack: " + e.stack);
         throw e;
     }
 }
 
+try {
+
 // Load / Store
-var IMPORTS = USE_ASM + 'var H=new glob.Uint8Array(heap); var i4=glob.SIMD.int32x4; var load=i4.load; var store=i4.store;';
+var IMPORTS = USE_ASM + 'var H=new glob.Uint8Array(heap); var i4=glob.SIMD.int32x4; var ci4=i4.check; var load=i4.load; var store=i4.store;';
 
 //      Bad number of args
 assertAsmTypeFail('glob', 'ffi', 'heap', IMPORTS + "function f(){load();} return f");
 assertAsmTypeFail('glob', 'ffi', 'heap', IMPORTS + "function f(){load(3);} return f");
 assertAsmTypeFail('glob', 'ffi', 'heap', IMPORTS + "function f(){load(3, 4, 5);} return f");
 
 //      Bad type of args
 assertAsmTypeFail('glob', 'ffi', 'heap', IMPORTS + "function f(){load(3, 5);} return f");
@@ -58,58 +60,60 @@ asI32[SIZE_TA - 3] = 3;
 asI32[SIZE_TA - 2] = 2;
 asI32[SIZE_TA - 1] = 1;
 
 assertAsmTypeFail('glob', 'ffi', 'heap', IMPORTS + "function f(){load(H, -1);} return f");
 assertAsmTypeFail('glob', 'ffi', 'heap', IMPORTS + "function f(){load(H, " + (INT32_MAX + 1) + ");} return f");
 assertAsmTypeFail('glob', 'ffi', 'heap', IMPORTS + "function f(){load(H, " + (INT32_MAX + 1 - 15) + ");} return f");
 asmCompile('glob', 'ffi', 'heap', IMPORTS + "function f(){load(H, " + (INT32_MAX + 1 - 16) + ");} return f");
 
-assertAsmLinkFail(asmCompile('glob', 'ffi', 'heap', IMPORTS + "function f() {return i4(load(H, " + (BUF_MIN - 15) + "));} return f"), this, {}, buf);
-assertEqX4(asmLink(asmCompile('glob', 'ffi', 'heap', IMPORTS + "function f() {return i4(load(H, " + (BUF_MIN - 16) + "));} return f"), this, {}, buf)(), [4, 3, 2, 1]);
-assertEqX4(asmLink(asmCompile('glob', 'ffi', 'heap', IMPORTS + "function f() {return i4(load(H, " + BUF_MIN + " - 16 | 0));} return f"), this, {}, buf)(), [4, 3, 2, 1]);
+assertAsmLinkFail(asmCompile('glob', 'ffi', 'heap', IMPORTS + "function f() {return ci4(load(H, " + (BUF_MIN - 15) + "));} return f"), this, {}, buf);
+assertEqX4(asmLink(asmCompile('glob', 'ffi', 'heap', IMPORTS + "function f() {return ci4(load(H, " + (BUF_MIN - 16) + "));} return f"), this, {}, buf)(), [4, 3, 2, 1]);
+assertEqX4(asmLink(asmCompile('glob', 'ffi', 'heap', IMPORTS + "function f() {return ci4(load(H, " + BUF_MIN + " - 16 | 0));} return f"), this, {}, buf)(), [4, 3, 2, 1]);
 
 var CONSTANT_INDEX = 42;
 var CONSTANT_BYTE_INDEX = CONSTANT_INDEX << 2;
 
 var loadStoreCode = `
     "use asm";
 
     var H = new glob.Uint8Array(heap);
 
     var i4 = glob.SIMD.int32x4;
     var i4load = i4.load;
     var i4store = i4.store;
+    var ci4 = i4.check;
 
     var f4 = glob.SIMD.float32x4;
     var f4load = f4.load;
     var f4store = f4.store;
+    var cf4 = f4.check;
 
-    function f32l(i) { i=i|0; return f4(f4load(H, i|0)); }
-    function f32lcst() { return f4(f4load(H, ${CONSTANT_BYTE_INDEX})); }
-    function f32s(i, vec) { i=i|0; vec=f4(vec); f4store(H, i|0, vec); }
-    function f32scst(vec) { vec=f4(vec); f4store(H, ${CONSTANT_BYTE_INDEX}, vec); }
+    function f32l(i) { i=i|0; return cf4(f4load(H, i|0)); }
+    function f32lcst() { return cf4(f4load(H, ${CONSTANT_BYTE_INDEX})); }
+    function f32s(i, vec) { i=i|0; vec=cf4(vec); f4store(H, i|0, vec); }
+    function f32scst(vec) { vec=cf4(vec); f4store(H, ${CONSTANT_BYTE_INDEX}, vec); }
 
-    function i32l(i) { i=i|0; return i4(i4load(H, i|0)); }
-    function i32lcst() { return i4(i4load(H, ${CONSTANT_BYTE_INDEX})); }
-    function i32s(i, vec) { i=i|0; vec=i4(vec); i4store(H, i|0, vec); }
-    function i32scst(vec) { vec=i4(vec); i4store(H, ${CONSTANT_BYTE_INDEX}, vec); }
+    function i32l(i) { i=i|0; return ci4(i4load(H, i|0)); }
+    function i32lcst() { return ci4(i4load(H, ${CONSTANT_BYTE_INDEX})); }
+    function i32s(i, vec) { i=i|0; vec=ci4(vec); i4store(H, i|0, vec); }
+    function i32scst(vec) { vec=ci4(vec); i4store(H, ${CONSTANT_BYTE_INDEX}, vec); }
 
     function f32lbndcheck(i) {
         i=i|0;
         if ((i|0) > ${CONSTANT_BYTE_INDEX}) i=${CONSTANT_BYTE_INDEX};
         if ((i|0) < 0) i = 0;
-        return f4(f4load(H, i|0));
+        return cf4(f4load(H, i|0));
     }
     function f32sbndcheck(i, vec) {
         i=i|0;
-        vec=f4(vec);
+        vec=cf4(vec);
         if ((i|0) > ${CONSTANT_BYTE_INDEX}) i=${CONSTANT_BYTE_INDEX};
         if ((i|0) < 0) i = 0;
-        return f4(f4store(H, i|0, vec));
+        return cf4(f4store(H, i|0, vec));
     }
 
     return {
         f32l: f32l,
         f32lcst: f32lcst,
         f32s: f32s,
         f32scst: f32scst,
         f32lbndcheck: f32lbndcheck,
@@ -164,22 +168,22 @@ var code = `
         // set a constraint on the size of the heap
         var ptr = 0;
         ptr = u8[0xFFFF] | 0;
         // give a precise range to x
         x = (x>>0) > 5 ? 5 : x;
         x = (x>>0) < 0 ? 0 : x;
         // ptr value gets a precise range but the bounds check shouldn't get
         // eliminated.
-        return f4(f4l(u8, 0xFFFA + x | 0));
+        return f4l(u8, 0xFFFA + x | 0);
     }
 
     return g;
 `;
-assertThrowsInstanceOf(() =>asmLink(asmCompile('glob', 'ffi', 'heap', code), this, {}, new ArrayBuffer(0x10000))(0), RangeError);
+assertThrowsInstanceOf(() => asmLink(asmCompile('glob', 'ffi', 'heap', code), this, {}, new ArrayBuffer(0x10000))(0), RangeError);
 
 // Float32x4.store
 function f32s(n, v) { return m.f32s((n|0) << 2 | 0, v); };
 
 var vec  = SIMD.float32x4(5,6,7,8);
 var vec2 = SIMD.float32x4(0,1,2,3);
 
 reset();
@@ -269,16 +273,17 @@ for (var i = 0; i < SIZE; i++)
 // Partial loads and stores
 (function() {
 
 //      Variable indexes
 function MakeCodeFor(typeName) {
     return `
     "use asm";
     var type = glob.SIMD.${typeName};
+    var c = type.check;
 
     var lx = type.loadX;
     var lxy = type.loadXY;
     var lxyz = type.loadXYZ;
 
     var sx = type.storeX;
     var sxy = type.storeXY;
     var sxyz = type.storeXYZ;
@@ -288,23 +293,23 @@ function MakeCodeFor(typeName) {
     function loadX(i) { i=i|0; return lx(u8, i); }
     function loadXY(i) { i=i|0; return lxy(u8, i); }
     function loadXYZ(i) { i=i|0; return lxyz(u8, i); }
 
     function loadCstX() { return lx(u8, 41 << 2); }
     function loadCstXY() { return lxy(u8, 41 << 2); }
     function loadCstXYZ() { return lxyz(u8, 41 << 2); }
 
-    function storeX(i, x) { i=i|0; x=type(x); return sx(u8, i, x); }
-    function storeXY(i, x) { i=i|0; x=type(x); return sxy(u8, i, x); }
-    function storeXYZ(i, x) { i=i|0; x=type(x); return sxyz(u8, i, x); }
+    function storeX(i, x) { i=i|0; x=c(x); return sx(u8, i, x); }
+    function storeXY(i, x) { i=i|0; x=c(x); return sxy(u8, i, x); }
+    function storeXYZ(i, x) { i=i|0; x=c(x); return sxyz(u8, i, x); }
 
-    function storeCstX(x) { x=type(x); return sx(u8, 41 << 2, x); }
-    function storeCstXY(x) { x=type(x); return sxy(u8, 41 << 2, x); }
-    function storeCstXYZ(x) { x=type(x); return sxyz(u8, 41 << 2, x); }
+    function storeCstX(x) { x=c(x); return sx(u8, 41 << 2, x); }
+    function storeCstXY(x) { x=c(x); return sxy(u8, 41 << 2, x); }
+    function storeCstXYZ(x) { x=c(x); return sxyz(u8, 41 << 2, x); }
 
     return {
         loadX: loadX,
         loadXY: loadXY,
         loadXYZ: loadXYZ,
         loadCstX: loadCstX,
         loadCstXY: loadCstXY,
         loadCstXYZ: loadCstXYZ,
@@ -500,8 +505,10 @@ TestPartialLoads(mint32x4, i32,
             (i) => i + 1 | 0,
             (i) => -i | 0,
             (i) => i * 2 | 0,
             (i) => 42);
 
 TestPartialStores(mint32x4, i32, 'int32x4', 42, -3, 13, 37);
 
 })();
+
+} catch (e) { print('stack: ', e.stack); throw e }
--- a/js/src/jit-test/tests/asm.js/testSIMD.js
+++ b/js/src/jit-test/tests/asm.js/testSIMD.js
@@ -5,20 +5,22 @@ var heap = new ArrayBuffer(0x10000);
 const DEBUG = false;
 
 if (!isSimdAvailable() || typeof SIMD === 'undefined') {
     DEBUG && print("won't run tests as simd extensions aren't activated yet");
     quit(0);
 }
 
 const I32 = 'var i4 = glob.SIMD.int32x4;'
+const CI32 = 'var ci4 = i4.check;'
 const I32A = 'var i4a = i4.add;'
 const I32S = 'var i4s = i4.sub;'
 const I32M = 'var i4m = i4.mul;'
 const F32 = 'var f4 = glob.SIMD.float32x4;'
+const CF32 = 'var cf4 = f4.check;'
 const F32A = 'var f4a = f4.add;'
 const F32S = 'var f4s = f4.sub;'
 const F32M = 'var f4m = f4.mul;'
 const F32D = 'var f4d = f4.div;'
 const FROUND = 'var f32=glob.Math.fround;'
 
 const INT32_MAX = Math.pow(2, 31) - 1;
 const INT32_MIN = INT32_MAX + 1 | 0;
@@ -32,25 +34,25 @@ function assertEqX4(real, expected, asse
     assertFunc(real.x, expected[0]);
     assertFunc(real.y, expected[1]);
     assertFunc(real.z, expected[2]);
     assertFunc(real.w, expected[3]);
 }
 
 function CheckI4(header, code, expected) {
     // code needs to contain a local called x
-    header = USE_ASM + I32 + F32 + header;
-    var observed = asmLink(asmCompile('glob', header + ';function f() {' + code + ';return i4(x)} return f'), this)();
+    header = USE_ASM + I32 + CI32 + F32 + header;
+    var observed = asmLink(asmCompile('glob', header + ';function f() {' + code + ';return ci4(x)} return f'), this)();
     assertEqX4(observed, expected);
 }
 
 function CheckF4(header, code, expected) {
     // code needs to contain a local called x
-    header = USE_ASM + F32 + header;
-    var observed = asmLink(asmCompile('glob', header + ';function f() {' + code + ';return f4(x)} return f'), this)();
+    header = USE_ASM + F32 + CF32 + header;
+    var observed = asmLink(asmCompile('glob', header + ';function f() {' + code + ';return cf4(x)} return f'), this)();
     assertEqX4(observed, expected.map(Math.fround));
 }
 
 try {
 
 // 1. Constructors
 
 // 1.1 Compilation
@@ -114,37 +116,37 @@ assertAsmTypeFail('glob', USE_ASM + I32 
 assertAsmTypeFail('glob', USE_ASM + I32 + "function f(i) {i=i|0; var z=0; return i * i4(1,2,3,4) | 0;} return f");
 assertAsmTypeFail('glob', USE_ASM + I32 + "function f(i) {var x=i4(1,2,3,i4(4,5,6,7))} return f");
 assertAsmTypeFail('glob', USE_ASM + I32 + F32 + "function f(i) {var x=i4(1,2,3,f4(4,5,6,7))} return f");
 assertAsmTypeFail('glob', USE_ASM + I32 + F32 + "function f(i) {var x=f4(1,2,3,i4(4,5,6,7))} return f");
 
 assertAsmTypeFail('glob', USE_ASM + I32 + "function f() {return +i4(1,2,3,4)} return f");
 assertAsmTypeFail('glob', USE_ASM + I32 + "function f() {return i4(1,2,3,4)|0} return f");
 assertAsmTypeFail('glob', USE_ASM + I32 + FROUND + "function f() {return f32(i4(1,2,3,4))} return f");
-assertAsmTypeFail('glob', USE_ASM + I32 + F32 + "function f() {return f4(i4(1,2,3,4))} return f");
+assertAsmTypeFail('glob', USE_ASM + I32 + F32 + CF32 + "function f() {return cf4(i4(1,2,3,4))} return f");
 
 assertAsmTypeFail('glob', USE_ASM + F32 + "function f() {return +f4(1,2,3,4)} return f");
 assertAsmTypeFail('glob', USE_ASM + F32 + "function f() {return f4(1,2,3,4)|0} return f");
 assertAsmTypeFail('glob', USE_ASM + F32 + FROUND + "function f() {return f32(f4(1,2,3,4))} return f");
-assertAsmTypeFail('glob', USE_ASM + I32 + F32 + "function f() {return i4(f4(1,2,3,4))} return f");
+assertAsmTypeFail('glob', USE_ASM + I32 + CI32 + F32 + "function f() {return ci4(f4(1,2,3,4))} return f");
 
 assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + "function f() {return i4(1,2,3,4);} return f"), this)(), [1, 2, 3, 4]);
-assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + "function f() {return i4(i4(1,2,3,4));} return f"), this)(), [1, 2, 3, 4]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + "function f() {return ci4(i4(1,2,3,4));} return f"), this)(), [1, 2, 3, 4]);
 assertEqX4(asmLink(asmCompile('glob', USE_ASM + F32 + "function f() {return f4(1,2,3,4);} return f"), this)(), [1, 2, 3, 4]);
-assertEqX4(asmLink(asmCompile('glob', USE_ASM + F32 + "function f() {return f4(f4(1,2,3,4));} return f"), this)(), [1, 2, 3, 4]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + F32 + CF32 + "function f() {return cf4(f4(1,2,3,4));} return f"), this)(), [1, 2, 3, 4]);
 
 assertEq(asmLink(asmCompile('glob', USE_ASM + I32 + "function f() {i4(1,2,3,4);} return f"), this)(), undefined);
 assertEq(asmLink(asmCompile('glob', USE_ASM + F32 + "function f() {f4(1,2,3,4);} return f"), this)(), undefined);
 
 // Int32x4 ctor should accept int?
-assertEqX4(asmLink(asmCompile('glob', 'ffi', 'heap', USE_ASM + I32 + "var i32=new glob.Int32Array(heap); function f(i) {i=i|0; return i4(i4(i32[i>>2], 2, 3, 4))} return f"), this, {}, new ArrayBuffer(0x10000))(0x20000), [0, 2, 3, 4]);
+assertEqX4(asmLink(asmCompile('glob', 'ffi', 'heap', USE_ASM + I32 + CI32 + "var i32=new glob.Int32Array(heap); function f(i) {i=i|0; return ci4(i4(i32[i>>2], 2, 3, 4))} return f"), this, {}, new ArrayBuffer(0x10000))(0x20000), [0, 2, 3, 4]);
 // Float32x4 ctor should accept floatish (i.e. float || float? || floatish) and doublit
-assertEqX4(asmLink(asmCompile('glob', 'ffi', 'heap', USE_ASM + F32 + FROUND + "var h=new glob.Float32Array(heap); function f(i) {i=i|0; return f4(f4(h[i>>2], f32(2), f32(3), f32(4)))} return f"), this, {}, new ArrayBuffer(0x10000))(0x20000), [NaN, 2, 3, 4]);
-assertEqX4(asmLink(asmCompile('glob', USE_ASM + F32 + FROUND + "function f(i) {i=i|0; return f4(f4(f32(1) + f32(2), f32(2), f32(3), f32(4)))} return f"), this, {}, new ArrayBuffer(0x10000))(0x20000), [3, 2, 3, 4]);
-assertEqX4(asmLink(asmCompile('glob', USE_ASM + F32 + FROUND + "function f(i) {i=i|0; return f4(f4(f32(1) + f32(2), 2.0, 3.0, 4.0))} return f"), this, {}, new ArrayBuffer(0x10000))(0x20000), [3, 2, 3, 4]);
+assertEqX4(asmLink(asmCompile('glob', 'ffi', 'heap', USE_ASM + F32 + CF32 + FROUND + "var h=new glob.Float32Array(heap); function f(i) {i=i|0; return cf4(f4(h[i>>2], f32(2), f32(3), f32(4)))} return f"), this, {}, new ArrayBuffer(0x10000))(0x20000), [NaN, 2, 3, 4]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + F32 + CF32 + FROUND + "function f(i) {i=i|0; return cf4(f4(f32(1) + f32(2), f32(2), f32(3), f32(4)))} return f"), this, {}, new ArrayBuffer(0x10000))(0x20000), [3, 2, 3, 4]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + F32 + CF32 + FROUND + "function f(i) {i=i|0; return cf4(f4(f32(1) + f32(2), 2.0, 3.0, 4.0))} return f"), this, {}, new ArrayBuffer(0x10000))(0x20000), [3, 2, 3, 4]);
 
 // 1.3.2 Reading values out of lanes
 assertAsmTypeFail('glob', USE_ASM + "function f() {var x=1; return x.y | 0;} return f");
 assertAsmTypeFail('glob', USE_ASM + "function f() {var x=1; return (x + x).y | 0;} return f");
 assertAsmTypeFail('glob', USE_ASM + "function f() {var x=1.; return x.y | 0;} return f");
 assertAsmTypeFail('glob', USE_ASM + "var f32=glob.Math.fround;" + I32 + "function f() {var x=f32(1); return x.y | 0;} return f");
 
 assertAsmTypeFail('glob', USE_ASM + I32 + "function f() {var x=i4(1,2,3,4); return x.length|0;} return f");
@@ -235,104 +237,94 @@ CheckF4(FROUND, 'var x=f4(1,2,3,4); var 
 // Uses in ternary conditionals
 assertAsmTypeFail('glob', USE_ASM + F32 + "function f() {var x=f4(1,2,3,4); var c=4; c=x?c:c;} return f");
 assertAsmTypeFail('glob', USE_ASM + F32 + "function f() {var x=f4(1,2,3,4); var c=4; x=1?x:c;} return f");
 assertAsmTypeFail('glob', USE_ASM + F32 + "function f() {var x=f4(1,2,3,4); var c=4; x=1?c:x;} return f");
 assertAsmTypeFail('glob', USE_ASM + F32 + I32 + "function f() {var x=f4(1,2,3,4); var y=i4(1,2,3,4); x=1?x:y;} return f");
 assertAsmTypeFail('glob', USE_ASM + F32 + I32 + "function f() {var x=f4(1,2,3,4); var y=i4(1,2,3,4); x=1?y:y;} return f");
 
 CheckF4('', 'var x=f4(1,2,3,4); var y=f4(4,3,2,1); x=3?y:x', [4, 3, 2, 1]);
-assertEqX4(asmLink(asmCompile('glob', USE_ASM + F32 + "function f(x) {x=x|0; var v=f4(1,2,3,4); var w=f4(5,6,7,8); return f4(x?w:v);} return f"), this)(1), [5,6,7,8]);
-assertEqX4(asmLink(asmCompile('glob', USE_ASM + F32 + "function f(v) {v=f4(v); var w=f4(5,6,7,8); return f4(4?w:v);} return f"), this)(SIMD.float32x4(1,2,3,4)), [5,6,7,8]);
-assertEqX4(asmLink(asmCompile('glob', USE_ASM + F32 + "function f(v, x) {v=f4(v); x=x|0; var w=f4(5,6,7,8); return f4(x?w:v);} return f"), this)(SIMD.float32x4(1,2,3,4), 0), [1,2,3,4]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + F32 + CF32 + "function f(x) {x=x|0; var v=f4(1,2,3,4); var w=f4(5,6,7,8); return cf4(x?w:v);} return f"), this)(1), [5,6,7,8]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + F32 + CF32 + "function f(v) {v=cf4(v); var w=f4(5,6,7,8); return cf4(4?w:v);} return f"), this)(SIMD.float32x4(1,2,3,4)), [5,6,7,8]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + F32 + CF32 + "function f(v, x) {v=cf4(v); x=x|0; var w=f4(5,6,7,8); return cf4(x?w:v);} return f"), this)(SIMD.float32x4(1,2,3,4), 0), [1,2,3,4]);
 
 CheckI4('', 'var x=i4(1,2,3,4); var y=i4(4,3,2,1); x=(x.x|0)?y:x', [4, 3, 2, 1]);
-assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + "function f(x) {x=x|0; var v=i4(1,2,3,4); var w=i4(5,6,7,8); return i4(x?w:v);} return f"), this)(1), [5,6,7,8]);
-assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + "function f(v) {v=i4(v); var w=i4(5,6,7,8); return i4(4?w:v);} return f"), this)(SIMD.int32x4(1,2,3,4)), [5,6,7,8]);
-assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + "function f(v, x) {v=i4(v); x=x|0; var w=i4(5,6,7,8); return i4(x?w:v);} return f"), this)(SIMD.int32x4(1,2,3,4), 0), [1,2,3,4]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + "function f(x) {x=x|0; var v=i4(1,2,3,4); var w=i4(5,6,7,8); return ci4(x?w:v);} return f"), this)(1), [5,6,7,8]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + "function f(v) {v=ci4(v); var w=i4(5,6,7,8); return ci4(4?w:v);} return f"), this)(SIMD.int32x4(1,2,3,4)), [5,6,7,8]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + "function f(v, x) {v=ci4(v); x=x|0; var w=i4(5,6,7,8); return ci4(x?w:v);} return f"), this)(SIMD.int32x4(1,2,3,4), 0), [1,2,3,4]);
 
 // 1.3.4 Return values
-assertAsmTypeFail('glob', USE_ASM + I32 + "function f() {var x=1; return i4(x)} return f");
-assertAsmTypeFail('glob', USE_ASM + I32 + "function f() {var x=1; return i4(x + x)} return f");
-assertAsmTypeFail('glob', USE_ASM + I32 + "function f() {var x=1.; return i4(x)} return f");
-assertAsmTypeFail('glob', USE_ASM + I32 + FROUND + "function f() {var x=f32(1.); return i4(x)} return f");
+assertAsmTypeFail('glob', USE_ASM + I32 + CI32 + "function f() {var x=1; return ci4(x)} return f");
+assertAsmTypeFail('glob', USE_ASM + I32 + CI32 + "function f() {var x=1; return ci4(x + x)} return f");
+assertAsmTypeFail('glob', USE_ASM + I32 + CI32 + "function f() {var x=1.; return ci4(x)} return f");
+assertAsmTypeFail('glob', USE_ASM + I32 + CI32 + FROUND + "function f() {var x=f32(1.); return ci4(x)} return f");
 
-assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + "function f() {var x=i4(1,2,3,4); return i4(x)} return f"), this)(), [1,2,3,4]);
-assertEqX4(asmLink(asmCompile('glob', USE_ASM + F32 + "function f() {var x=f4(1,2,3,4); return f4(x)} return f"), this)(), [1,2,3,4]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + "function f() {var x=i4(1,2,3,4); return ci4(x)} return f"), this)(), [1,2,3,4]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + F32 + CF32 + "function f() {var x=f4(1,2,3,4); return cf4(x)} return f"), this)(), [1,2,3,4]);
 
 // 1.3.5 Coerce and pass arguments
 // Via check
-const CHECK_I32 = 'var c=i4.check;';
-
-assertAsmTypeFail('glob', USE_ASM + I32 + CHECK_I32 + "function f() {c();} return f");
-assertAsmTypeFail('glob', USE_ASM + I32 + CHECK_I32 + "function f(x) {x=i4(x); c(x, x);} return f");
-assertAsmTypeFail('glob', USE_ASM + I32 + CHECK_I32 + "function f() {c(1);} return f");
-assertAsmTypeFail('glob', USE_ASM + I32 + CHECK_I32 + "function f() {c(1.);} return f");
-assertAsmTypeFail('glob', USE_ASM + I32 + CHECK_I32 + FROUND + "function f() {c(f32(1.));} return f");
-assertAsmTypeFail('glob', USE_ASM + I32 + CHECK_I32 + F32 + "function f(x) {x=f4(x); c(x);} return f");
-assertAsmTypeFail('glob', USE_ASM + I32 + CHECK_I32 + "function f(x) {x=i4(x); return 1 + c(x) | 0;} return f");
+assertAsmTypeFail('glob', USE_ASM + I32 + CI32 + "function f() {ci4();} return f");
+assertAsmTypeFail('glob', USE_ASM + I32 + CI32 + "function f(x) {x=ci4(x); ci4(x, x);} return f");
+assertAsmTypeFail('glob', USE_ASM + I32 + CI32 + "function f() {ci4(1);} return f");
+assertAsmTypeFail('glob', USE_ASM + I32 + CI32 + "function f() {ci4(1.);} return f");
+assertAsmTypeFail('glob', USE_ASM + I32 + CI32 + FROUND + "function f() {ci4(f32(1.));} return f");
+assertAsmTypeFail('glob', USE_ASM + I32 + CI32 + F32 + CF32 + "function f(x) {x=cf4(x); ci4(x);} return f");
+assertAsmTypeFail('glob', USE_ASM + I32 + CI32 + "function f(x) {x=ci4(x); return 1 + ci4(x) | 0;} return f");
 
 var i32x4 = SIMD.int32x4(1, 3, 3, 7);
-assertEq(asmLink(asmCompile('glob', USE_ASM + I32 + CHECK_I32 + "function f(x) {x=c(x)} return f"), this)(i32x4), undefined);
-assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + CHECK_I32 + "function f(x) {x=i4(x); return c(x);} return f"), this)(i32x4), [1,3,3,7]);
-
-const CHECK_F32 = 'var c=f4.check;';
+assertEq(asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + "function f(x) {x=ci4(x)} return f"), this)(i32x4), undefined);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + "function f(x) {x=ci4(x); return ci4(x);} return f"), this)(i32x4), [1,3,3,7]);
 
-assertAsmTypeFail('glob', USE_ASM + F32 + CHECK_F32 + "function f() {c();} return f");
-assertAsmTypeFail('glob', USE_ASM + F32 + CHECK_F32 + "function f(x) {x=f4(x); c(x, x);} return f");
-assertAsmTypeFail('glob', USE_ASM + F32 + CHECK_F32 + "function f() {c(1);} return f");
-assertAsmTypeFail('glob', USE_ASM + F32 + CHECK_F32 + "function f() {c(1.);} return f");
-assertAsmTypeFail('glob', USE_ASM + F32 + CHECK_F32 + FROUND + "function f() {c(f32(1.));} return f");
-assertAsmTypeFail('glob', USE_ASM + F32 + CHECK_F32 + I32 + "function f(x) {x=i4(x); c(x);} return f");
-assertAsmTypeFail('glob', USE_ASM + F32 + CHECK_F32 + "function f(x) {x=f4(x); return 1 + c(x) | 0;} return f");
+assertAsmTypeFail('glob', USE_ASM + F32 + CF32 + "function f() {cf4();} return f");
+assertAsmTypeFail('glob', USE_ASM + F32 + CF32 + "function f(x) {x=cf4(x); cf4(x, x);} return f");
+assertAsmTypeFail('glob', USE_ASM + F32 + CF32 + "function f() {cf4(1);} return f");
+assertAsmTypeFail('glob', USE_ASM + F32 + CF32 + "function f() {cf4(1.);} return f");
+assertAsmTypeFail('glob', USE_ASM + F32 + CF32 + FROUND + "function f() {cf4(f32(1.));} return f");
+assertAsmTypeFail('glob', USE_ASM + F32 + CF32 + F32 + CF32 + "function f(x) {x=cf4(x); cf4(x);} return f");
+assertAsmTypeFail('glob', USE_ASM + F32 + CF32 + "function f(x) {x=cf4(x); return 1 + cf4(x) | 0;} return f");
 
 var f32x4 = SIMD.float32x4(13.37, 42.42, -0, NaN);
-assertEq(asmLink(asmCompile('glob', USE_ASM + F32 + CHECK_F32 + "function f(x) {x=c(x)} return f"), this)(f32x4), undefined);
-assertEqX4(asmLink(asmCompile('glob', USE_ASM + F32 + CHECK_F32 + "function f(x) {x=c(x); return c(x);} return f"), this)(f32x4),
-           [Math.fround(13.37), Math.fround(42.42), -0, NaN]);
+assertEq(asmLink(asmCompile('glob', USE_ASM + F32 + CF32 + "function f(x) {x=cf4(x)} return f"), this)(f32x4), undefined);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + F32 + CF32 + "function f(x) {x=cf4(x); return cf4(x);} return f"), this)(f32x4), [13.37, 42.42, -0, NaN].map(Math.fround));
 
 // Legacy coercions
 assertAsmTypeFail('glob', USE_ASM + I32 + "function f(x) {x=i4();} return f");
+assertAsmTypeFail('glob', USE_ASM + I32 + "function f(x) {x=i4(x);} return f");
 assertAsmTypeFail('glob', USE_ASM + I32 + "function f(x) {x=i4(1,2,3,4);} return f");
 assertAsmTypeFail('glob', USE_ASM + I32 + "function f(x,y) {x=i4(y);y=+y} return f");
+assertAsmTypeFail('glob', USE_ASM + I32 + CI32 + "function f(x) {x=ci4(x); return i4(x);} return f");
 
 assertAsmTypeFail('glob', USE_ASM + I32 + "function f(x) {return +i4(1,2,3,4)} return f");
 assertAsmTypeFail('glob', USE_ASM + I32 + "function f(x) {return 0|i4(1,2,3,4)} return f");
 assertAsmTypeFail('glob', USE_ASM + I32 + FROUND + "function f(x) {return f32(i4(1,2,3,4))} return f");
 assertAsmTypeFail('glob', USE_ASM + I32 + F32 + "function f(x) {return f4(i4(1,2,3,4))} return f");
-
-var i32x4 = SIMD.int32x4(1, 3, 3, 7);
-assertEq(asmLink(asmCompile('glob', USE_ASM + I32 + "function f(x) {x=i4(x)} return f"), this)(i32x4), undefined);
-assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + "function f(x) {x=i4(x); return i4(x);} return f"), this)(i32x4), [1,3,3,7]);
+assertAsmTypeFail('glob', USE_ASM + F32 + CF32 + "function f(x) {x=cf4(x); return f4(x);} return f");
 
-var f32x4 = SIMD.float32x4(13.37, 42.42, -0, NaN);
-assertEq(asmLink(asmCompile('glob', USE_ASM + F32 + "function f(x) {x=f4(x)} return f"), this)(f32x4), undefined);
-assertEqX4(asmLink(asmCompile('glob', USE_ASM + F32 + "function f(x) {x=f4(x); return f4(x);} return f"), this)(f32x4),
-           [Math.fround(13.37), Math.fround(42.42), -0, NaN]);
 
 function assertCaught(f) {
     var caught = false;
     try {
         f.apply(null, Array.prototype.slice.call(arguments, 1));
     } catch (e) {
         DEBUG && print('Assert caught: ', e, '\n', e.stack);
         assertEq(e instanceof TypeError, true);
         caught = true;
     }
     assertEq(caught, true);
 }
 
-var f = asmLink(asmCompile('glob', USE_ASM + F32 + "function f(x) {x=f4(x); return f4(x);} return f"), this);
+var f = asmLink(asmCompile('glob', USE_ASM + F32 + CF32 + "function f(x) {x=cf4(x); return cf4(x);} return f"), this);
 assertCaught(f);
 assertCaught(f, 1);
 assertCaught(f, {});
 assertCaught(f, "I sincerely am a SIMD typed object.");
 assertCaught(f, SIMD.int32x4(1,2,3,4));
 
-var f = asmLink(asmCompile('glob', USE_ASM + I32 + "function f(x) {x=i4(x); return i4(x);} return f"), this);
+var f = asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + "function f(x) {x=ci4(x); return ci4(x);} return f"), this);
 assertCaught(f);
 assertCaught(f, 1);
 assertCaught(f, {});
 assertCaught(f, "I sincerely am a SIMD typed object.");
 assertCaught(f, SIMD.float32x4(4,3,2,1));
 
 // 1.3.6 Globals
 // 1.3.6.1 Local globals
@@ -340,18 +332,18 @@ assertCaught(f, SIMD.float32x4(4,3,2,1))
 assertAsmTypeFail('glob', USE_ASM + I32 + "var g=i4(1,2,3,4); function f() {var x=4; x=g|0;} return f");
 assertAsmTypeFail('glob', USE_ASM + I32 + "var g=i4(1,2,3,4); function f() {var x=4.; x=+g;} return f");
 assertAsmTypeFail('glob', USE_ASM + I32 + "var g=i4(1,2,3,4); var f32=glob.Math.fround; function f() {var x=f32(4.); x=f32(g);} return f");
 
 assertAsmTypeFail('glob', USE_ASM + F32 + "var g=f4(1., 2., 3., 4.); function f() {var x=4; x=g|0;} return f");
 assertAsmTypeFail('glob', USE_ASM + F32 + "var g=f4(1., 2., 3., 4.); function f() {var x=4.; x=+g;} return f");
 assertAsmTypeFail('glob', USE_ASM + F32 + "var g=f4(1., 2., 3., 4.); var f32=glob.Math.fround; function f() {var x=f32(4.); x=f32(g);} return f");
 
-assertAsmTypeFail('glob', USE_ASM + F32 + I32 + "var g=f4(1., 2., 3., 4.); function f() {var x=i4(1,2,3,4); x=i4(g);} return f");
-assertAsmTypeFail('glob', USE_ASM + I32 + F32 + "var g=i4(1,2,3,4); function f() {var x=f4(1.,2.,3.,4.); x=f4(g);} return f");
+assertAsmTypeFail('glob', USE_ASM + F32 + I32 + CI32 + "var g=f4(1., 2., 3., 4.); function f() {var x=i4(1,2,3,4); x=ci4(g);} return f");
+assertAsmTypeFail('glob', USE_ASM + I32 + F32 + CF32 + "var g=i4(1,2,3,4); function f() {var x=f4(1.,2.,3.,4.); x=cf4(g);} return f");
 
 assertAsmTypeFail('glob', USE_ASM + I32 + "var g=0; function f() {var x=i4(1,2,3,4); x=g|0;} return f");
 assertAsmTypeFail('glob', USE_ASM + I32 + "var g=0.; function f() {var x=i4(1,2,3,4); x=+g;} return f");
 assertAsmTypeFail('glob', USE_ASM + I32 + "var f32=glob.Math.fround; var g=f32(0.); function f() {var x=i4(1,2,3,4); x=f32(g);} return f");
 
 assertAsmTypeFail('glob', USE_ASM + F32 + "var g=0; function f() {var x=f4(0.,0.,0.,0.); x=g|0;} return f");
 assertAsmTypeFail('glob', USE_ASM + F32 + "var g=0.; function f() {var x=f4(0.,0.,0.,0.); x=+g;} return f");
 assertAsmTypeFail('glob', USE_ASM + F32 + "var f32=glob.Math.fround; var g=f32(0.); function f() {var x=f4(0.,0.,0.,0.); x=f32(g);} return f");
@@ -367,55 +359,55 @@ CheckF4('var x=f4(1,2,3,4)', '', [1, 2, 
 assertAsmTypeFail('glob', USE_ASM + I32 + "var g=i4(1,2,3,4); function f() {var x=4; g=x|0;} return f");
 assertAsmTypeFail('glob', USE_ASM + I32 + "var g=i4(1,2,3,4); function f() {var x=4.; g=+x;} return f");
 assertAsmTypeFail('glob', USE_ASM + I32 + "var g=i4(1,2,3,4); var f32=glob.Math.fround; function f() {var x=f32(4.); g=f32(x);} return f");
 
 assertAsmTypeFail('glob', USE_ASM + F32 + "var g=f4(1., 2., 3., 4.); function f() {var x=4; g=x|0;} return f");
 assertAsmTypeFail('glob', USE_ASM + F32 + "var g=f4(1., 2., 3., 4.); function f() {var x=4.; g=+x;} return f");
 assertAsmTypeFail('glob', USE_ASM + F32 + "var g=f4(1., 2., 3., 4.); var f32=glob.Math.fround; function f() {var x=f32(4.); g=f32(x);} return f");
 
-assertAsmTypeFail('glob', USE_ASM + F32 + I32 + "var g=f4(1., 2., 3., 4.); function f() {var x=i4(1,2,3,4); g=i4(x);} return f");
-assertAsmTypeFail('glob', USE_ASM + F32 + I32 + "var g=f4(1., 2., 3., 4.); function f() {var x=i4(1,2,3,4); g=f4(x);} return f");
-assertAsmTypeFail('glob', USE_ASM + I32 + F32 + "var g=i4(1,2,3,4); function f() {var x=f4(1.,2.,3.,4.); g=f4(x);} return f");
-assertAsmTypeFail('glob', USE_ASM + I32 + F32 + "var g=i4(1,2,3,4); function f() {var x=f4(1.,2.,3.,4.); g=i4(x);} return f");
+assertAsmTypeFail('glob', USE_ASM + F32 + I32 + CI32 + "var g=f4(1., 2., 3., 4.); function f() {var x=i4(1,2,3,4); g=ci4(x);} return f");
+assertAsmTypeFail('glob', USE_ASM + F32 + I32 + CF32 + "var g=f4(1., 2., 3., 4.); function f() {var x=i4(1,2,3,4); g=cf4(x);} return f");
+assertAsmTypeFail('glob', USE_ASM + I32 + F32 + CF32 + "var g=i4(1,2,3,4); function f() {var x=f4(1.,2.,3.,4.); g=cf4(x);} return f");
+assertAsmTypeFail('glob', USE_ASM + I32 + F32 + CI32 + "var g=i4(1,2,3,4); function f() {var x=f4(1.,2.,3.,4.); g=ci4(x);} return f");
 
 CheckI4('var x=i4(0,0,0,0);', 'x=i4(1,2,3,4)', [1,2,3,4]);
 CheckF4('var x=f4(0.,0.,0.,0.);', 'x=f4(5.,3.,4.,2.)', [5,3,4,2]);
 
 CheckI4('var x=i4(0,0,0,0); var y=42; var z=3.9; var w=13.37', 'x=i4(1,2,3,4); y=24; z=4.9; w=23.10;', [1,2,3,4]);
 CheckF4('var x=f4(0,0,0,0); var y=42; var z=3.9; var w=13.37', 'x=f4(1,2,3,4); y=24; z=4.9; w=23.10;', [1,2,3,4]);
 
 // 1.3.6.2 Imported globals
 // Read
-var int32x4 = asmLink(asmCompile('glob', 'ffi', USE_ASM + I32 + "var g=i4(ffi.g); function f() {return i4(g)} return f"), this, {g: SIMD.int32x4(1,2,3,4)})();
+var int32x4 = asmLink(asmCompile('glob', 'ffi', USE_ASM + I32 + CI32 + "var g=ci4(ffi.g); function f() {return ci4(g)} return f"), this, {g: SIMD.int32x4(1,2,3,4)})();
 assertEq(int32x4.x, 1);
 assertEq(int32x4.y, 2);
 assertEq(int32x4.z, 3);
 assertEq(int32x4.w, 4);
 
 for (var v of [1, {}, "totally legit SIMD variable", SIMD.float32x4(1,2,3,4)])
-    assertCaught(asmCompile('glob', 'ffi', USE_ASM + I32 + "var g=i4(ffi.g); function f() {return i4(g)} return f"), this, {g: v});
+    assertCaught(asmCompile('glob', 'ffi', USE_ASM + I32 + CI32 + "var g=ci4(ffi.g); function f() {return ci4(g)} return f"), this, {g: v});
 
-var float32x4 = asmLink(asmCompile('glob', 'ffi', USE_ASM + F32 + "var g=f4(ffi.g); function f() {return f4(g)} return f"), this, {g: SIMD.float32x4(1,2,3,4)})();
+var float32x4 = asmLink(asmCompile('glob', 'ffi', USE_ASM + F32 + CF32 + "var g=cf4(ffi.g); function f() {return cf4(g)} return f"), this, {g: SIMD.float32x4(1,2,3,4)})();
 assertEq(float32x4.x, 1);
 assertEq(float32x4.y, 2);
 assertEq(float32x4.z, 3);
 assertEq(float32x4.w, 4);
 
 for (var v of [1, {}, "totally legit SIMD variable", SIMD.int32x4(1,2,3,4)])
-    assertCaught(asmCompile('glob', 'ffi', USE_ASM + F32 + "var g=f4(ffi.g); function f() {return f4(g)} return f"), this, {g: v});
+    assertCaught(asmCompile('glob', 'ffi', USE_ASM + F32 + CF32 + "var g=cf4(ffi.g); function f() {return cf4(g)} return f"), this, {g: v});
 
 // Write
-var int32x4 = asmLink(asmCompile('glob', 'ffi', USE_ASM + I32 + "var g=i4(ffi.g); function f() {g=i4(4,5,6,7); return i4(g)} return f"), this, {g: SIMD.int32x4(1,2,3,4)})();
+var int32x4 = asmLink(asmCompile('glob', 'ffi', USE_ASM + I32 + CI32 + "var g=ci4(ffi.g); function f() {g=i4(4,5,6,7); return ci4(g)} return f"), this, {g: SIMD.int32x4(1,2,3,4)})();
 assertEq(int32x4.x, 4);
 assertEq(int32x4.y, 5);
 assertEq(int32x4.z, 6);
 assertEq(int32x4.w, 7);
 
-var float32x4 = asmLink(asmCompile('glob', 'ffi', USE_ASM + F32 + "var g=f4(ffi.g); function f() {g=f4(4.,5.,6.,7.); return f4(g)} return f"), this, {g: SIMD.float32x4(1,2,3,4)})();
+var float32x4 = asmLink(asmCompile('glob', 'ffi', USE_ASM + F32 + CF32 + "var g=cf4(ffi.g); function f() {g=f4(4.,5.,6.,7.); return cf4(g)} return f"), this, {g: SIMD.float32x4(1,2,3,4)})();
 assertEq(float32x4.x, 4);
 assertEq(float32x4.y, 5);
 assertEq(float32x4.z, 6);
 assertEq(float32x4.w, 7);
 
 // 2. SIMD operations
 // 2.1 Compilation
 assertAsmTypeFail('glob', USE_ASM + "var add = int32x4.add; return {}");
@@ -453,41 +445,41 @@ assertAsmTypeFail('glob', USE_ASM + I32 
 assertAsmTypeFail('glob', USE_ASM + I32 + I32A + "function f() {var x=i4(0,0,0,0); var y=4; y=i4a(x, x);} return f");
 assertAsmTypeFail('glob', USE_ASM + I32 + F32 + I32A + "function f() {var x=i4(0,0,0,0); var y=f4(4,3,2,1); x=i4a(x, y);} return f");
 assertAsmTypeFail('glob', USE_ASM + I32 + F32 + I32A + "function f() {var x=i4(0,0,0,0); var y=f4(4,3,2,1); y=i4a(x, y);} return f");
 assertAsmTypeFail('glob', USE_ASM + I32 + F32 + I32A + "function f() {var x=i4(0,0,0,0); var y=f4(4,3,2,1); y=i4a(x, x);} return f");
 assertAsmTypeFail('glob', USE_ASM + I32 + F32 + F32A + "function f() {var x=i4(0,0,0,0); var y=f4(4,3,2,1); y=f4a(x, x);} return f");
 assertAsmTypeFail('glob', USE_ASM + I32 + F32 + F32A + "function f() {var x=i4(0,0,0,0); var y=f4(4,3,2,1); y=f4a(x, y);} return f");
 assertAsmTypeFail('glob', USE_ASM + I32 + F32 + F32A + "function f() {var x=i4(0,0,0,0); var y=f4(4,3,2,1); x=f4a(y, y);} return f");
 
-assertAsmTypeFail('glob', USE_ASM + I32 + I32A + 'function f() {var x=i4(1,2,3,4); var y=0; y=i4(x,x)|0} return f');
-assertAsmTypeFail('glob', USE_ASM + I32 + I32A + 'function f() {var x=i4(1,2,3,4); var y=0.; y=+i4(x,x)} return f');
+assertAsmTypeFail('glob', USE_ASM + I32 + I32A + 'function f() {var x=i4(1,2,3,4); var y=0; y=i4a(x,x)|0} return f');
+assertAsmTypeFail('glob', USE_ASM + I32 + I32A + 'function f() {var x=i4(1,2,3,4); var y=0.; y=+i4a(x,x)} return f');
 
 CheckI4(I32A, 'var z=i4(1,2,3,4); var y=i4(0,1,0,3); var x=i4(0,0,0,0); x=i4a(z,y)', [1,3,3,7]);
 CheckI4(I32A, 'var x=i4(2,3,4,5); var y=i4(0,1,0,3); x=i4a(x,y)', [2,4,4,8]);
 CheckI4(I32A, 'var x=i4(1,2,3,4); x=i4a(x,x)', [2,4,6,8]);
 CheckI4(I32A, 'var x=i4(' + INT32_MAX + ',2,3,4); var y=i4(1,1,0,3); x=i4a(x,y)', [INT32_MIN,3,3,7]);
-CheckI4(I32A, 'var x=i4(' + INT32_MAX + ',2,3,4); var y=i4(1,1,0,3); x=i4(i4a(x,y))', [INT32_MIN,3,3,7]);
+CheckI4(I32A, 'var x=i4(' + INT32_MAX + ',2,3,4); var y=i4(1,1,0,3); x=ci4(i4a(x,y))', [INT32_MIN,3,3,7]);
 
 CheckF4(F32A, 'var x=f4(1,2,3,4); x=f4a(x,x)', [2,4,6,8]);
 CheckF4(F32A, 'var x=f4(1,2,3,4); var y=f4(4,3,5,2); x=f4a(x,y)', [5,5,8,6]);
 CheckF4(F32A, 'var x=f4(13.37,2,3,4); var y=f4(4,3,5,2); x=f4a(x,y)', [Math.fround(13.37) + 4,5,8,6]);
-CheckF4(F32A, 'var x=f4(13.37,2,3,4); var y=f4(4,3,5,2); x=f4(f4a(x,y))', [Math.fround(13.37) + 4,5,8,6]);
+CheckF4(F32A, 'var x=f4(13.37,2,3,4); var y=f4(4,3,5,2); x=cf4(f4a(x,y))', [Math.fround(13.37) + 4,5,8,6]);
 
 // 2.3.2. Subtracts
 CheckI4(I32S, 'var x=i4(1,2,3,4); var y=i4(-1,1,0,2); x=i4s(x,y)', [2,1,3,2]);
 CheckI4(I32S, 'var x=i4(5,4,3,2); var y=i4(1,2,3,4); x=i4s(x,y)', [4,2,0,-2]);
 CheckI4(I32S, 'var x=i4(1,2,3,4); x=i4s(x,x)', [0,0,0,0]);
 CheckI4(I32S, 'var x=i4(' + INT32_MIN + ',2,3,4); var y=i4(1,1,0,3); x=i4s(x,y)', [INT32_MAX,1,3,1]);
-CheckI4(I32S, 'var x=i4(' + INT32_MIN + ',2,3,4); var y=i4(1,1,0,3); x=i4(i4s(x,y))', [INT32_MAX,1,3,1]);
+CheckI4(I32S, 'var x=i4(' + INT32_MIN + ',2,3,4); var y=i4(1,1,0,3); x=ci4(i4s(x,y))', [INT32_MAX,1,3,1]);
 
 CheckF4(F32S, 'var x=f4(1,2,3,4); x=f4s(x,x)', [0,0,0,0]);
 CheckF4(F32S, 'var x=f4(1,2,3,4); var y=f4(4,3,5,2); x=f4s(x,y)', [-3,-1,-2,2]);
 CheckF4(F32S, 'var x=f4(13.37,2,3,4); var y=f4(4,3,5,2); x=f4s(x,y)', [Math.fround(13.37) - 4,-1,-2,2]);
-CheckF4(F32S, 'var x=f4(13.37,2,3,4); var y=f4(4,3,5,2); x=f4(f4s(x,y))', [Math.fround(13.37) - 4,-1,-2,2]);
+CheckF4(F32S, 'var x=f4(13.37,2,3,4); var y=f4(4,3,5,2); x=cf4(f4s(x,y))', [Math.fround(13.37) - 4,-1,-2,2]);
 
 // 2.3.3. Multiplications / Divisions
 assertAsmTypeFail('glob', USE_ASM + I32 + "var f4d=i4.div; function f() {} return f");
 
 CheckI4(I32M, 'var x=i4(1,2,3,4); var y=i4(-1,1,0,2); x=i4m(x,y)', [-1,2,0,8]);
 CheckI4(I32M, 'var x=i4(5,4,3,2); var y=i4(1,2,3,4); x=i4m(x,y)', [5,8,9,8]);
 CheckI4(I32M, 'var x=i4(1,2,3,4); x=i4m(x,x)', [1,4,9,16]);
 (function() {
@@ -496,44 +488,44 @@ CheckI4(I32M, 'var x=i4(1,2,3,4); x=i4m(
             [imul(m, 2), imul(m, -3), imul(M, 4), imul(M, -5)]);
     CheckI4(I32M, `var x=i4(${m},${m}, ${M}, ${M}); var y=i4(${m}, ${M}, ${m}, ${M}); x=i4m(x,y)`,
             [imul(m, m), imul(m, M), imul(M, m), imul(M, M)]);
 })();
 
 CheckF4(F32M, 'var x=f4(1,2,3,4); x=f4m(x,x)', [1,4,9,16]);
 CheckF4(F32M, 'var x=f4(1,2,3,4); var y=f4(4,3,5,2); x=f4m(x,y)', [4,6,15,8]);
 CheckF4(F32M, 'var x=f4(13.37,2,3,4); var y=f4(4,3,5,2); x=f4m(x,y)', [Math.fround(13.37) * 4,6,15,8]);
-CheckF4(F32M, 'var x=f4(13.37,2,3,4); var y=f4(4,3,5,2); x=f4(f4m(x,y))', [Math.fround(13.37) * 4,6,15,8]);
+CheckF4(F32M, 'var x=f4(13.37,2,3,4); var y=f4(4,3,5,2); x=cf4(f4m(x,y))', [Math.fround(13.37) * 4,6,15,8]);
 
 var f32x4 = SIMD.float32x4(0, NaN, -0, NaN);
 var another = SIMD.float32x4(NaN, -1, -0, NaN);
-assertEqX4(asmLink(asmCompile('glob', USE_ASM + F32 + F32M + "function f(x, y) {x=f4(x); y=f4(y); x=f4m(x,y); return f4(x);} return f"), this)(f32x4, another), [NaN, NaN, 0, NaN]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + F32 + F32M + CF32 + "function f(x, y) {x=cf4(x); y=cf4(y); x=f4m(x,y); return cf4(x);} return f"), this)(f32x4, another), [NaN, NaN, 0, NaN]);
 
 CheckF4(F32D, 'var x=f4(1,2,3,4); x=f4d(x,x)', [1,1,1,1]);
 CheckF4(F32D, 'var x=f4(1,2,3,4); var y=f4(4,3,5,2); x=f4d(x,y)', [1/4,2/3,3/5,2]);
 CheckF4(F32D, 'var x=f4(13.37,1,1,4); var y=f4(4,0,-0.,2); x=f4d(x,y)', [Math.fround(13.37) / 4,+Infinity,-Infinity,2]);
 
 var f32x4 = SIMD.float32x4(0, 0, -0, NaN);
 var another = SIMD.float32x4(0, -0, 0, 0);
-assertEqX4(asmLink(asmCompile('glob', USE_ASM + F32 + F32D + "function f(x,y) {x=f4(x); y=f4(y); x=f4d(x,y); return f4(x);} return f"), this)(f32x4, another), [NaN, NaN, NaN, NaN]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + F32 + F32D + CF32 + "function f(x,y) {x=cf4(x); y=cf4(y); x=f4d(x,y); return cf4(x);} return f"), this)(f32x4, another), [NaN, NaN, NaN, NaN]);
 
 // Unary arithmetic operators
 function CheckUnaryF4(op, checkFunc, assertFunc) {
-    var _ = asmLink(asmCompile('glob', USE_ASM + F32 + 'var op=f4.' + op + '; function f(x){x=f4(x); return f4(op(x)); } return f'), this);
+    var _ = asmLink(asmCompile('glob', USE_ASM + F32 + CF32 + 'var op=f4.' + op + '; function f(x){x=cf4(x); return cf4(op(x)); } return f'), this);
     return function(input) {
         var simd = SIMD.float32x4(input[0], input[1], input[2], input[3]);
 
         var exp = input.map(Math.fround).map(checkFunc).map(Math.fround);
         var obs = _(simd);
         assertEqX4(obs, exp, assertFunc);
     }
 }
 
 function CheckUnaryI4(op, checkFunc) {
-    var _ = asmLink(asmCompile('glob', USE_ASM + I32 + 'var op=i4.' + op + '; function f(x){x=i4(x); return i4(op(x)); } return f'), this);
+    var _ = asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + 'var op=i4.' + op + '; function f(x){x=ci4(x); return ci4(op(x)); } return f'), this);
     return function(input) {
         var simd = SIMD.int32x4(input[0], input[1], input[2], input[3]);
         assertEqX4(_(simd), input.map(checkFunc).map(function(x) { return x | 0}));
     }
 }
 
 CheckUnaryI4('neg', function(x) { return -x })([1, -2, INT32_MIN, INT32_MAX]);
 CheckUnaryI4('not', function(x) { return ~x })([1, -2, INT32_MIN, INT32_MAX]);
@@ -617,29 +609,33 @@ CheckF4(F32MAXNUM + FROUND + 'var NaN = 
 
 // With
 const WXF = 'var w = f4.withX;';
 const WYF = 'var w = f4.withY;';
 const WZF = 'var w = f4.withZ;';
 const WWF = 'var w = f4.withW;';
 
 assertAsmTypeFail('glob', USE_ASM + F32 + WXF + "function f() {var x = f4(1,2,3,4); x = w(x, 1);} return f");
-assertAsmTypeFail('glob', USE_ASM + F32 + WXF + "function f() {var x = f4(1,2,3,4); x = w(x, 1.0);} return f");
 assertAsmTypeFail('glob', USE_ASM + F32 + WXF + "function f() {var x = f4(1,2,3,4); x = w(x, x);} return f");
 assertAsmTypeFail('glob', USE_ASM + F32 + WXF + FROUND + "function f() {var x = f4(1,2,3,4); x = w(1, f32(1));} return f");
 assertAsmTypeFail('glob', USE_ASM + F32 + WXF + FROUND + "function f() {var x = f4(1,2,3,4); x = w(1., f32(1));} return f");
 assertAsmTypeFail('glob', USE_ASM + F32 + WXF + FROUND + "function f() {var x = f4(1,2,3,4); x = w(f32(1), f32(1));} return f");
 assertAsmTypeFail('glob', USE_ASM + I32 + F32 + WXF + FROUND + "function f() {var x = f4(1,2,3,4); var y = i4(1,2,3,4); x = w(y, f32(1));} return f");
 
 CheckF4(WXF + FROUND, 'var x = f4(1,2,3,4); x = w(x, f32(13.37));', [Math.fround(13.37), 2, 3, 4]);
 CheckF4(WYF + FROUND, 'var x = f4(1,2,3,4); x = w(x, f32(13.37));', [1, Math.fround(13.37), 3, 4]);
 CheckF4(WZF + FROUND, 'var x = f4(1,2,3,4); x = w(x, f32(13.37));', [1, 2, Math.fround(13.37), 4]);
 CheckF4(WWF + FROUND, 'var x = f4(1,2,3,4); x = w(x, f32(13.37));', [1, 2, 3, Math.fround(13.37)]);
 CheckF4(WWF + FROUND, 'var x = f4(1,2,3,4); x = w(x, f32(13.37) + f32(6.63));', [1, 2, 3, Math.fround(Math.fround(13.37) + Math.fround(6.63))]);
 
+CheckF4(WXF + FROUND, 'var x = f4(1,2,3,4); x = w(x, 13.37);', [Math.fround(13.37), 2, 3, 4]);
+CheckF4(WYF + FROUND, 'var x = f4(1,2,3,4); x = w(x, 13.37);', [1, Math.fround(13.37), 3, 4]);
+CheckF4(WZF + FROUND, 'var x = f4(1,2,3,4); x = w(x, 13.37);', [1, 2, Math.fround(13.37), 4]);
+CheckF4(WWF + FROUND, 'var x = f4(1,2,3,4); x = w(x, 13.37);', [1, 2, 3, Math.fround(13.37)]);
+
 const WXI = 'var w = i4.withX;';
 const WYI = 'var w = i4.withY;';
 const WZI = 'var w = i4.withZ;';
 const WWI = 'var w = i4.withW;';
 CheckI4(WXI, 'var x = i4(1,2,3,4); x = w(x, 42);', [42, 2, 3, 4]);
 CheckI4(WYI, 'var x = i4(1,2,3,4); x = w(x, 42);', [1, 42, 3, 4]);
 CheckI4(WZI, 'var x = i4(1,2,3,4); x = w(x, 42);', [1, 2, 42, 4]);
 CheckI4(WWI, 'var x = i4(1,2,3,4); x = w(x, 42);', [1, 2, 3, 42]);
@@ -724,26 +720,26 @@ CheckI4(GEF32 + 'const nan = glob.NaN; c
 const CVTIF = 'var cvt=f4.fromInt32x4;';
 const CVTFI = 'var cvt=i4.fromFloat32x4;';
 
 assertAsmTypeFail('glob', USE_ASM + I32 + "var cvt=i4.fromInt32x4; return {}");
 assertAsmTypeFail('glob', USE_ASM + F32 + "var cvt=f4.fromFloat32x4; return {}");
 assertAsmTypeFail('glob', USE_ASM + I32 + F32 + CVTIF + "function f() {var x=i4(1,2,3,4); x=cvt(x);} return f");
 assertAsmTypeFail('glob', USE_ASM + I32 + F32 + CVTIF + "function f() {var x=f4(1,2,3,4); x=cvt(x);} return f");
 
-var f = asmLink(asmCompile('glob', USE_ASM + I32 + F32 + CVTIF + 'function f(x){x=i4(x); var y=f4(0,0,0,0); y=cvt(x); return f4(y);} return f'), this);
+var f = asmLink(asmCompile('glob', USE_ASM + I32 + F32 + CF32 + CI32 + CVTIF + 'function f(x){x=ci4(x); var y=f4(0,0,0,0); y=cvt(x); return cf4(y);} return f'), this);
 assertEqX4(f(SIMD.int32x4(1,2,3,4)), [1, 2, 3, 4]);
 assertEqX4(f(SIMD.int32x4(0,INT32_MIN,INT32_MAX,-1)), [0, Math.fround(INT32_MIN), Math.fround(INT32_MAX), -1]);
 
 // TODO amend tests once int32x4.fromFloat32x4 is fully specified, when float
 // values can't be converted into an int32 without overflowing.  In these
 // tests, we assume x86/x64, so a conversion which failed will return the
 // undefined int32 value. See also bug 1068028.
 const UNDEFINED_INT32 = 0x80000000 | 0;
-var f = asmLink(asmCompile('glob', USE_ASM + I32 + F32 + CVTFI + 'function f(x){x=f4(x); var y=i4(0,0,0,0); y=cvt(x); return i4(y);} return f'), this);
+var f = asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + F32 + CF32 + CVTFI + 'function f(x){x=cf4(x); var y=i4(0,0,0,0); y=cvt(x); return ci4(y);} return f'), this);
 assertEqX4(f(SIMD.float32x4(1,2,3,4)), [1, 2, 3, 4]);
 assertEqX4(f(SIMD.float32x4(NaN,Infinity,-Infinity,-0)), [UNDEFINED_INT32, UNDEFINED_INT32, UNDEFINED_INT32, 0]);
 
 // Cast operators
 const CVTIFB = 'var cvt=f4.fromInt32x4Bits;';
 const CVTFIB = 'var cvt=i4.fromFloat32x4Bits;';
 
 var cast = (function() {
@@ -766,29 +762,29 @@ var cast = (function() {
     }
 })();
 
 assertAsmTypeFail('glob', USE_ASM + I32 + "var cvt=i4.fromInt32x4; return {}");
 assertAsmTypeFail('glob', USE_ASM + F32 + "var cvt=f4.fromFloat32x4; return {}");
 assertAsmTypeFail('glob', USE_ASM + I32 + F32 + CVTIFB + "function f() {var x=i4(1,2,3,4); x=cvt(x);} return f");
 assertAsmTypeFail('glob', USE_ASM + I32 + F32 + CVTIFB + "function f() {var x=f4(1,2,3,4); x=cvt(x);} return f");
 
-var f = asmLink(asmCompile('glob', USE_ASM + I32 + F32 + CVTIFB + 'function f(x){x=i4(x); var y=f4(0,0,0,0); y=cvt(x); return f4(y);} return f'), this);
+var f = asmLink(asmCompile('glob', USE_ASM + I32 + F32 + CVTIFB + CF32 + CI32 + 'function f(x){x=ci4(x); var y=f4(0,0,0,0); y=cvt(x); return cf4(y);} return f'), this);
 assertEqX4(f(SIMD.int32x4(1,2,3,4)), [1, 2, 3, 4].map(cast.fromInt32Bits));
 assertEqX4(f(SIMD.int32x4(0,INT32_MIN,INT32_MAX,-1)), [0, INT32_MIN, INT32_MAX, -1].map(cast.fromInt32Bits));
 
-var f = asmLink(asmCompile('glob', USE_ASM + I32 + F32 + F32A + CVTIFB + 'function f(x){x=i4(x); var y=f4(0,0,0,0); var z=f4(1,1,1,1); y=cvt(x); y=f4a(y, z); return f4(y)} return f'), this);
+var f = asmLink(asmCompile('glob', USE_ASM + I32 + F32 + F32A + CVTIFB + CF32 + CI32 + 'function f(x){x=ci4(x); var y=f4(0,0,0,0); var z=f4(1,1,1,1); y=cvt(x); y=f4a(y, z); return cf4(y)} return f'), this);
 assertEqX4(f(SIMD.int32x4(1,2,3,4)), [1, 2, 3, 4].map(cast.fromInt32Bits).map((x) => x+1));
 assertEqX4(f(SIMD.int32x4(0,INT32_MIN,INT32_MAX,-1)), [0, INT32_MIN, INT32_MAX, -1].map(cast.fromInt32Bits).map((x) => x+1));
 
-var f = asmLink(asmCompile('glob', USE_ASM + I32 + F32 + CVTFIB + 'function f(x){x=f4(x); var y=i4(0,0,0,0); y=cvt(x); return i4(y);} return f'), this);
+var f = asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + F32 + CF32 + CVTFIB + 'function f(x){x=cf4(x); var y=i4(0,0,0,0); y=cvt(x); return ci4(y);} return f'), this);
 assertEqX4(f(SIMD.float32x4(1,2,3,4)), [1, 2, 3, 4].map(cast.fromFloat32Bits));
 assertEqX4(f(SIMD.float32x4(-0,NaN,+Infinity,-Infinity)), [-0, NaN, +Infinity, -Infinity].map(cast.fromFloat32Bits));
 
-var f = asmLink(asmCompile('glob', USE_ASM + I32 + F32 + I32A + CVTFIB + 'function f(x){x=f4(x); var y=i4(0,0,0,0); var z=i4(1,1,1,1); y=cvt(x); y=i4a(y,z); return i4(y);} return f'), this);
+var f = asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + F32 + CF32 + I32A + CVTFIB + 'function f(x){x=cf4(x); var y=i4(0,0,0,0); var z=i4(1,1,1,1); y=cvt(x); y=i4a(y,z); return ci4(y);} return f'), this);
 assertEqX4(f(SIMD.float32x4(1,2,3,4)), [1, 2, 3, 4].map(cast.fromFloat32Bits).map((x) => x+1));
 assertEqX4(f(SIMD.float32x4(-0,NaN,+Infinity,-Infinity)), [-0, NaN, +Infinity, -Infinity].map(cast.fromFloat32Bits).map((x) => x+1));
 
 // Bitwise ops
 const ANDI32 = 'var andd=i4.and;';
 const ORI32 = 'var orr=i4.or;';
 const XORI32 = 'var xorr=i4.xor;';
 
@@ -821,34 +817,34 @@ CheckF4(ANDF32, 'var x=f4(42, 13.37,-1.4
 CheckF4(ORF32,  'var x=f4(42, 13.37,-1.42, 23.10); var y=f4(19.89, 2.4, 8.15, 16.36); x=orr(x,y)',  bitwise.or( [42, 13.37, -1.42, 23.10], [19.89, 2.4, 8.15, 16.36]));
 CheckF4(XORF32, 'var x=f4(42, 13.37,-1.42, 23.10); var y=f4(19.89, 2.4, 8.15, 16.36); x=xorr(x,y)', bitwise.xor([42, 13.37, -1.42, 23.10], [19.89, 2.4, 8.15, 16.36]));
 
 // Logical ops
 const LSHI = 'var lsh=i4.shiftLeftByScalar;'
 const RSHI = 'var rsh=i4.shiftRightArithmeticByScalar;'
 const URSHI = 'var ursh=i4.shiftRightLogicalByScalar;'
 
-assertAsmTypeFail('glob', USE_ASM + I32 + F32 + FROUND + LSHI + "function f() {var x=f4(1,2,3,4); return i4(lsh(x,f32(42)));} return f");
-assertAsmTypeFail('glob', USE_ASM + I32 + F32 + FROUND + LSHI + "function f() {var x=f4(1,2,3,4); return i4(lsh(x,42));} return f");
-assertAsmTypeFail('glob', USE_ASM + I32 + FROUND + LSHI + "function f() {var x=i4(1,2,3,4); return i4(lsh(x,42.0));} return f");
-assertAsmTypeFail('glob', USE_ASM + I32 + FROUND + LSHI + "function f() {var x=i4(1,2,3,4); return i4(lsh(x,f32(42)));} return f");
+assertAsmTypeFail('glob', USE_ASM + I32 + CI32 + F32 + FROUND + LSHI + "function f() {var x=f4(1,2,3,4); return ci4(lsh(x,f32(42)));} return f");
+assertAsmTypeFail('glob', USE_ASM + I32 + CI32 + F32 + FROUND + LSHI + "function f() {var x=f4(1,2,3,4); return ci4(lsh(x,42));} return f");
+assertAsmTypeFail('glob', USE_ASM + I32 + CI32 + FROUND + LSHI + "function f() {var x=i4(1,2,3,4); return ci4(lsh(x,42.0));} return f");
+assertAsmTypeFail('glob', USE_ASM + I32 + CI32 + FROUND + LSHI + "function f() {var x=i4(1,2,3,4); return ci4(lsh(x,f32(42)));} return f");
 
 var input = 'i4(0, 1, ' + INT32_MIN + ', ' + INT32_MAX + ')';
 var vinput = [0, 1, INT32_MIN, INT32_MAX];
 
 // TODO: What to do for masks > 31? Should we keep only the five low bits of
 // the mask (JS) or not (x86)?
 // Behave as x86 for now, fix when more broadly specified. See also bug 1068028
 function Lsh(i) {  if (i > 31) return () => 0; return function(x) { return (x << i) | 0 } }
 function Rsh(i) {  if (i > 31) return (x) => (x<0)?-1:0; return function(x) { return (x >> i) | 0 } }
 function Ursh(i) { if (i > 31) return () => 0; return function(x) { return (x >>> i) | 0 } }
 
-var asmLsh = asmLink(asmCompile('glob', USE_ASM + I32 + LSHI + 'function f(x, y){x=x|0;y=y|0; var v=' + input + ';return i4(lsh(v, x+y))} return f;'), this)
-var asmRsh = asmLink(asmCompile('glob', USE_ASM + I32 + RSHI + 'function f(x, y){x=x|0;y=y|0; var v=' + input + ';return i4(rsh(v, x+y))} return f;'), this)
-var asmUrsh = asmLink(asmCompile('glob', USE_ASM + I32 + URSHI + 'function f(x, y){x=x|0;y=y|0; var v=' + input + ';return i4(ursh(v, x+y))} return f;'), this)
+var asmLsh = asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + LSHI + 'function f(x, y){x=x|0;y=y|0; var v=' + input + ';return ci4(lsh(v, x+y))} return f;'), this)
+var asmRsh = asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + RSHI + 'function f(x, y){x=x|0;y=y|0; var v=' + input + ';return ci4(rsh(v, x+y))} return f;'), this)
+var asmUrsh = asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + URSHI + 'function f(x, y){x=x|0;y=y|0; var v=' + input + ';return ci4(ursh(v, x+y))} return f;'), this)
 
 for (var i = 1; i < 64; i++) {
     CheckI4(LSHI,  'var x=' + input + '; x=lsh(x, ' + i + ')',   vinput.map(Lsh(i)));
     CheckI4(RSHI,  'var x=' + input + '; x=rsh(x, ' + i + ')',   vinput.map(Rsh(i)));
     CheckI4(URSHI, 'var x=' + input + '; x=ursh(x, ' + i + ')',  vinput.map(Ursh(i)));
 
     assertEqX4(asmLsh(i, 3),  vinput.map(Lsh(i + 3)));
     assertEqX4(asmRsh(i, 3),  vinput.map(Rsh(i + 3)));
@@ -856,91 +852,91 @@ for (var i = 1; i < 64; i++) {
 }
 
 // Select
 const I32SEL = 'var i4sel = i4.select;'
 const F32SEL = 'var f4sel = f4.select;'
 const I32BSEL = 'var i4sel = i4.bitselect;'
 const F32BSEL = 'var f4sel = f4.bitselect;'
 
-assertAsmTypeFail('glob', USE_ASM + F32 + I32SEL + "function f() {var x=f4(1,2,3,4); return i4(i4sel(x,x,x));} return f");
-assertAsmTypeFail('glob', USE_ASM + I32 + F32 + I32SEL + "function f() {var m=f4(1,2,3,4); var x=i4(1,2,3,4); return i4(i4sel(m,x,x));} return f");
-assertAsmTypeFail('glob', USE_ASM + I32 + F32 + I32SEL + "function f() {var m=f4(1,2,3,4); var x=f4(1,2,3,4); return i4(i4sel(m,x,x));} return f");
-assertAsmTypeFail('glob', USE_ASM + I32 + F32 + I32SEL + "function f() {var m=i4(1,2,3,4); var x=f4(1,2,3,4); return i4(i4sel(m,x,x));} return f");
-assertAsmTypeFail('glob', USE_ASM + I32 + F32 + I32SEL + "function f() {var m=i4(1,2,3,4); var x=f4(1,2,3,4); var y=i4(5,6,7,8); return i4(i4sel(m,x,y));} return f");
-assertAsmTypeFail('glob', USE_ASM + I32 + F32 + I32SEL + "function f() {var m=i4(1,2,3,4); var x=i4(1,2,3,4); var y=f4(5,6,7,8); return i4(i4sel(m,x,y));} return f");
-assertAsmTypeFail('glob', USE_ASM + I32 + F32 + I32SEL + "function f() {var m=i4(1,2,3,4); var x=f4(1,2,3,4); var y=f4(5,6,7,8); return i4(i4sel(m,x,y));} return f");
+assertAsmTypeFail('glob', USE_ASM + I32 + F32 + CI32 + I32SEL + "function f() {var x=f4(1,2,3,4); return ci4(i4sel(x,x,x));} return f");
+assertAsmTypeFail('glob', USE_ASM + I32 + F32 + CI32 + I32SEL + "function f() {var m=f4(1,2,3,4); var x=i4(1,2,3,4); return ci4(i4sel(m,x,x));} return f");
+assertAsmTypeFail('glob', USE_ASM + I32 + F32 + CI32 + I32SEL + "function f() {var m=f4(1,2,3,4); var x=f4(1,2,3,4); return ci4(i4sel(m,x,x));} return f");
+assertAsmTypeFail('glob', USE_ASM + I32 + F32 + CI32 + I32SEL + "function f() {var m=i4(1,2,3,4); var x=f4(1,2,3,4); return ci4(i4sel(m,x,x));} return f");
+assertAsmTypeFail('glob', USE_ASM + I32 + F32 + CI32 + I32SEL + "function f() {var m=i4(1,2,3,4); var x=f4(1,2,3,4); var y=i4(5,6,7,8); return ci4(i4sel(m,x,y));} return f");
+assertAsmTypeFail('glob', USE_ASM + I32 + F32 + CI32 + I32SEL + "function f() {var m=i4(1,2,3,4); var x=i4(1,2,3,4); var y=f4(5,6,7,8); return ci4(i4sel(m,x,y));} return f");
+assertAsmTypeFail('glob', USE_ASM + I32 + F32 + CI32 + I32SEL + "function f() {var m=i4(1,2,3,4); var x=f4(1,2,3,4); var y=f4(5,6,7,8); return ci4(i4sel(m,x,y));} return f");
 
-assertAsmTypeFail('glob', USE_ASM + F32 + F32SEL + "function f() {var m=f4(1,2,3,4); return f4(f4sel(x,x,x));} return f");
-assertAsmTypeFail('glob', USE_ASM + I32 + F32 + F32SEL + "function f() {var m=f4(1,2,3,4); var x=i4(1,2,3,4); return f4(f4sel(m,x,x));} return f");
-assertAsmTypeFail('glob', USE_ASM + I32 + F32 + F32SEL + "function f() {var m=f4(1,2,3,4); var x=f4(1,2,3,4); return f4(f4sel(m,x,x));} return f");
-assertAsmTypeFail('glob', USE_ASM + I32 + F32 + F32SEL + "function f() {var m=i4(1,2,3,4); var x=f4(1,2,3,4); var y=i4(5,6,7,8); return f4(f4sel(m,x,y));} return f");
-assertAsmTypeFail('glob', USE_ASM + I32 + F32 + F32SEL + "function f() {var m=i4(1,2,3,4); var x=i4(1,2,3,4); var y=f4(5,6,7,8); return f4(f4sel(m,x,y));} return f");
+assertAsmTypeFail('glob', USE_ASM + F32 + CF32 + F32SEL + "function f() {var m=f4(1,2,3,4); return cf4(f4sel(x,x,x));} return f");
+assertAsmTypeFail('glob', USE_ASM + I32 + F32 + CF32 + F32SEL + "function f() {var m=f4(1,2,3,4); var x=i4(1,2,3,4); return cf4(f4sel(m,x,x));} return f");
+assertAsmTypeFail('glob', USE_ASM + I32 + F32 + CF32 + F32SEL + "function f() {var m=f4(1,2,3,4); var x=f4(1,2,3,4); return cf4(f4sel(m,x,x));} return f");
+assertAsmTypeFail('glob', USE_ASM + I32 + F32 + CF32 + F32SEL + "function f() {var m=i4(1,2,3,4); var x=f4(1,2,3,4); var y=i4(5,6,7,8); return cf4(f4sel(m,x,y));} return f");
+assertAsmTypeFail('glob', USE_ASM + I32 + F32 + CF32 + F32SEL + "function f() {var m=i4(1,2,3,4); var x=i4(1,2,3,4); var y=f4(5,6,7,8); return cf4(f4sel(m,x,y));} return f");
 
 // These pass with select but not bitselect
-assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + I32SEL + "function f() {var m=i4(0,0,0,0); var x=i4(1,2,3,4); var y=i4(5,6,7,8); return i4(i4sel(m,x,y)); } return f"), this)(), [5, 6, 7, 8]);
-assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + I32SEL + "function f() {var m=i4(-1,-2,-3,-42); var x=i4(1,2,3,4); var y=i4(5,6,7,8); return i4(i4sel(m,x,y)); } return f"), this)(), [1, 2, 3, 4]);
-assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + I32SEL + "function f() {var m=i4(1,-1,2,-2); var x=i4(1,2,3,4); var y=i4(5,6,7,8); return i4(i4sel(m,x,y)); } return f"), this)(), [5, 2, 7, 4]);
-assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + I32SEL + "function f() {var m=i4(42,45,-42,-47); var x=i4(1,2,3,4); var y=i4(5,6,7,8); return i4(i4sel(m,x,y)); } return f"), this)(), [5, 6, 3, 4]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + I32SEL + "function f() {var m=i4(0,0,0,0); var x=i4(1,2,3,4); var y=i4(5,6,7,8); return ci4(i4sel(m,x,y)); } return f"), this)(), [5, 6, 7, 8]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + I32SEL + "function f() {var m=i4(-1,-2,-3,-42); var x=i4(1,2,3,4); var y=i4(5,6,7,8); return ci4(i4sel(m,x,y)); } return f"), this)(), [1, 2, 3, 4]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + I32SEL + "function f() {var m=i4(1,-1,2,-2); var x=i4(1,2,3,4); var y=i4(5,6,7,8); return ci4(i4sel(m,x,y)); } return f"), this)(), [5, 2, 7, 4]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + I32SEL + "function f() {var m=i4(42,45,-42,-47); var x=i4(1,2,3,4); var y=i4(5,6,7,8); return ci4(i4sel(m,x,y)); } return f"), this)(), [5, 6, 3, 4]);
 
-assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + F32 + F32SEL + "function f() {var m=i4(0,0,0,0); var x=f4(1,2,3,4); var y=f4(5,6,7,8); return f4(f4sel(m,x,y)); } return f"), this)(), [5, 6, 7, 8]);
-assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + F32 + F32SEL + "function f() {var m=i4(-1,-2,-3,-42); var x=f4(1,2,3,4); var y=f4(5,6,7,8); return f4(f4sel(m,x,y)); } return f"), this)(), [1, 2, 3, 4]);
-assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + F32 + F32SEL + "function f() {var m=i4(1,-1,2,-2); var x=f4(1,2,3,4); var y=f4(5,6,7,8); return f4(f4sel(m,x,y)); } return f"), this)(), [5, 2, 7, 4]);
-assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + F32 + F32SEL + "function f() {var m=i4(42,45,-42,-47); var x=f4(1,2,3,4); var y=f4(5,6,7,8); return f4(f4sel(m,x,y)); } return f"), this)(), [5, 6, 3, 4]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + F32 + CF32 + F32SEL + "function f() {var m=i4(0,0,0,0); var x=f4(1,2,3,4); var y=f4(5,6,7,8); return cf4(f4sel(m,x,y)); } return f"), this)(), [5, 6, 7, 8]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + F32 + CF32 + F32SEL + "function f() {var m=i4(-1,-2,-3,-42); var x=f4(1,2,3,4); var y=f4(5,6,7,8); return cf4(f4sel(m,x,y)); } return f"), this)(), [1, 2, 3, 4]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + F32 + CF32 + F32SEL + "function f() {var m=i4(1,-1,2,-2); var x=f4(1,2,3,4); var y=f4(5,6,7,8); return cf4(f4sel(m,x,y)); } return f"), this)(), [5, 2, 7, 4]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + F32 + CF32 + F32SEL + "function f() {var m=i4(42,45,-42,-47); var x=f4(1,2,3,4); var y=f4(5,6,7,8); return cf4(f4sel(m,x,y)); } return f"), this)(), [5, 6, 3, 4]);
 
 // These pass for both select and bitselect
-assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + I32SEL + "function f() {var m=i4(0,0,0,0); var x=i4(1,2,3,4); var y=i4(5,6,7,8); return i4(i4sel(m,x,y)); } return f"), this)(), [5, 6, 7, 8]);
-assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + I32SEL + "function f() {var m=i4(0xffffffff,0xffffffff,0xffffffff,0xffffffff); var x=i4(1,2,3,4); var y=i4(5,6,7,8); return i4(i4sel(m,x,y)); } return f"), this)(), [1, 2, 3, 4]);
-assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + I32SEL + "function f() {var m=i4(0,0xffffffff,0,0xffffffff); var x=i4(1,2,3,4); var y=i4(5,6,7,8); return i4(i4sel(m,x,y)); } return f"), this)(), [5, 2, 7, 4]);
-assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + I32SEL + "function f() {var m=i4(0,0,0xffffffff,0xffffffff); var x=i4(1,2,3,4); var y=i4(5,6,7,8); return i4(i4sel(m,x,y)); } return f"), this)(), [5, 6, 3, 4]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + I32SEL + "function f() {var m=i4(0,0,0,0); var x=i4(1,2,3,4); var y=i4(5,6,7,8); return ci4(i4sel(m,x,y)); } return f"), this)(), [5, 6, 7, 8]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + I32SEL + "function f() {var m=i4(0xffffffff,0xffffffff,0xffffffff,0xffffffff); var x=i4(1,2,3,4); var y=i4(5,6,7,8); return ci4(i4sel(m,x,y)); } return f"), this)(), [1, 2, 3, 4]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + I32SEL + "function f() {var m=i4(0,0xffffffff,0,0xffffffff); var x=i4(1,2,3,4); var y=i4(5,6,7,8); return ci4(i4sel(m,x,y)); } return f"), this)(), [5, 2, 7, 4]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + I32SEL + "function f() {var m=i4(0,0,0xffffffff,0xffffffff); var x=i4(1,2,3,4); var y=i4(5,6,7,8); return ci4(i4sel(m,x,y)); } return f"), this)(), [5, 6, 3, 4]);
 
-assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + F32 + F32SEL + "function f() {var m=i4(0,0,0,0); var x=f4(1,2,3,4); var y=f4(5,6,7,8); return f4(f4sel(m,x,y)); } return f"), this)(), [5, 6, 7, 8]);
-assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + F32 + F32SEL + "function f() {var m=i4(0xffffffff,0xffffffff,0xffffffff,0xffffffff); var x=f4(1,2,3,4); var y=f4(5,6,7,8); return f4(f4sel(m,x,y)); } return f"), this)(), [1, 2, 3, 4]);
-assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + F32 + F32SEL + "function f() {var m=i4(0,0xffffffff,0,0xffffffff); var x=f4(1,2,3,4); var y=f4(5,6,7,8); return f4(f4sel(m,x,y)); } return f"), this)(), [5, 2, 7, 4]);
-assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + F32 + F32SEL + "function f() {var m=i4(0,0,0xffffffff,0xffffffff); var x=f4(1,2,3,4); var y=f4(5,6,7,8); return f4(f4sel(m,x,y)); } return f"), this)(), [5, 6, 3, 4]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + F32 + CF32 + F32SEL + "function f() {var m=i4(0,0,0,0); var x=f4(1,2,3,4); var y=f4(5,6,7,8); return cf4(f4sel(m,x,y)); } return f"), this)(), [5, 6, 7, 8]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + F32 + CF32 + F32SEL + "function f() {var m=i4(0xffffffff,0xffffffff,0xffffffff,0xffffffff); var x=f4(1,2,3,4); var y=f4(5,6,7,8); return cf4(f4sel(m,x,y)); } return f"), this)(), [1, 2, 3, 4]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + F32 + CF32 + F32SEL + "function f() {var m=i4(0,0xffffffff,0,0xffffffff); var x=f4(1,2,3,4); var y=f4(5,6,7,8); return cf4(f4sel(m,x,y)); } return f"), this)(), [5, 2, 7, 4]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + F32 + CF32 + F32SEL + "function f() {var m=i4(0,0,0xffffffff,0xffffffff); var x=f4(1,2,3,4); var y=f4(5,6,7,8); return cf4(f4sel(m,x,y)); } return f"), this)(), [5, 6, 3, 4]);
 
-assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + I32BSEL + "function f() {var m=i4(0,0,0,0); var x=i4(1,2,3,4); var y=i4(5,6,7,8); return i4(i4sel(m,x,y)); } return f"), this)(), [5, 6, 7, 8]);
-assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + I32BSEL + "function f() {var m=i4(0xffffffff,0xffffffff,0xffffffff,0xffffffff); var x=i4(1,2,3,4); var y=i4(5,6,7,8); return i4(i4sel(m,x,y)); } return f"), this)(), [1, 2, 3, 4]);
-assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + I32BSEL + &qu