Merge mozilla-central to autoland
authorDorel Luca <dluca@mozilla.com>
Thu, 03 May 2018 13:01:33 +0300
changeset 472879 321c252382be24f9165c663fca66473f658b0004
parent 472878 fd7d5c81670c3ec281fdd547e19132aeacec2f8b (current diff)
parent 472866 a2d1d4158bb4718d8bb31e1284e133aa99273600 (diff)
child 472880 7135781f4a792dc5f6c415c94a57e96a1288e2dd
push id1728
push userjlund@mozilla.com
push dateMon, 18 Jun 2018 21:12:27 +0000
treeherdermozilla-release@c296fde26f5f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge mozilla-central to autoland
--- a/dom/security/nsContentSecurityManager.cpp
+++ b/dom/security/nsContentSecurityManager.cpp
@@ -157,17 +157,17 @@ nsContentSecurityManager::AllowInsecureR
                                   "BlockSubresourceRedirectToData",
                                   params, ArrayLength(params));
   return false;
 }
 
 /* static */ nsresult
 nsContentSecurityManager::CheckFTPSubresourceLoad(nsIChannel* aChannel)
 {
-  // We dissallow using FTP resources as a subresource everywhere.
+  // We dissallow using FTP resources as a subresource almost everywhere.
   // The only valid way to use FTP resources is loading it as
   // a top level document.
   if (!mozilla::net::nsIOService::BlockFTPSubresources()) {
     return NS_OK;
   }
 
   nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo();
   if (!loadInfo) {
@@ -186,16 +186,24 @@ nsContentSecurityManager::CheckFTPSubres
     return NS_OK;
   }
 
   bool isFtpURI = (NS_SUCCEEDED(uri->SchemeIs("ftp", &isFtpURI)) && isFtpURI);
   if (!isFtpURI) {
     return NS_OK;
   }
 
+  // Allow loading FTP subresources in FTP documents, like XML.
+  nsIPrincipal* triggeringPrincipal = loadInfo->TriggeringPrincipal();
+  nsCOMPtr<nsIURI> triggeringURI;
+  triggeringPrincipal->GetURI(getter_AddRefs(triggeringURI));
+  if (triggeringURI && nsContentUtils::SchemeIs(triggeringURI, "ftp")) {
+    return NS_OK;
+  }
+
   nsCOMPtr<nsIDocument> doc;
   if (nsINode* node = loadInfo->LoadingNode()) {
     doc = node->OwnerDoc();
   }
 
   nsAutoCString spec;
   uri->GetSpec(spec);
   NS_ConvertUTF8toUTF16 specUTF16(NS_UnescapeURL(spec));
--- a/js/src/builtin/TypedArray.js
+++ b/js/src/builtin/TypedArray.js
@@ -1020,40 +1020,42 @@ function TypedArraySlice(start, end) {
                 : std_Math_min(relativeEnd, len);
 
     // Step 8.
     var count = std_Math_max(final - k, 0);
 
     // Step 9.
     var A = TypedArraySpeciesCreateWithLength(O, count);
 
-    // Steps 10-13 (Not implemented, bug 1140152).
-
     // Steps 14-15.
     if (count > 0) {
-        // Step 14.a.
-        var n = 0;
-
         // Steps 14.b.ii, 15.b.
         if (buffer === null) {
             // A typed array previously using inline storage may acquire a
             // buffer, so we must check with the source.
             buffer = ViewedArrayBufferIfReified(O);
         }
 
         if (IsDetachedBuffer(buffer))
             ThrowTypeError(JSMSG_TYPED_ARRAY_DETACHED);
 
-        // Step 14.b.
-        while (k < final) {
-            // Steps 14.b.i-v.
-            A[n++] = O[k++];
+        // Steps 10-13, 15.
+        var sliced = TypedArrayBitwiseSlice(O, A, k | 0, count | 0);
+
+        // Step 14.
+        if (!sliced) {
+            // Step 14.a.
+            var n = 0;
+
+            // Step 14.b.
+            while (k < final) {
+                // Steps 14.b.i-v.
+                A[n++] = O[k++];
+            }
         }
-
-        // FIXME: Implement step 15 (bug 1140152).
     }
 
     // Step 16.
     return A;
 }
 
 // ES6 draft rev30 (2014/12/24) 22.2.3.25 %TypedArray%.prototype.some(callbackfn[, thisArg]).
 function TypedArraySome(callbackfn/*, thisArg*/) {
--- a/js/src/tests/jstests.list
+++ b/js/src/tests/jstests.list
@@ -140,19 +140,16 @@ skip script test262/built-ins/TypedArray
 skip script test262/built-ins/TypedArrayConstructors/internals/HasProperty/key-is-not-canonical-index.js
 skip script test262/built-ins/TypedArrayConstructors/internals/HasProperty/key-is-not-integer.js
 skip script test262/built-ins/TypedArrayConstructors/internals/Set/key-is-minus-zero.js
 skip script test262/built-ins/TypedArrayConstructors/internals/Set/key-is-not-canonical-index.js
 skip script test262/built-ins/TypedArrayConstructors/internals/Set/key-is-not-integer.js
 skip script test262/built-ins/TypedArrayConstructors/internals/Set/key-is-out-of-bounds.js
 skip script test262/built-ins/TypedArrayConstructors/internals/Set/tonumber-value-throws.js
 
-# https://bugzilla.mozilla.org/show_bug.cgi?id=1140152
-skip script test262/built-ins/TypedArray/prototype/slice/bit-precision.js
-
 # https://bugzilla.mozilla.org/show_bug.cgi?id=1317405
 skip script test262/language/computed-property-names/class/static/method-number.js
 skip script test262/language/computed-property-names/class/static/method-string.js
 skip script test262/language/computed-property-names/class/static/method-symbol.js
 
 # https://bugzilla.mozilla.org/show_bug.cgi?id=1286997
 # Bug 1286997 probably doesn't cover all spec violations.
 skip script test262/language/expressions/assignment/S11.13.1_A5_T5.js
new file mode 100644
--- /dev/null
+++ b/js/src/tests/non262/TypedArray/slice-bitwise.js
@@ -0,0 +1,153 @@
+// Copies bytes bit-wise if source and target type are the same.
+// Only detectable when using floating point typed arrays.
+const float32Constructors = anyTypedArrayConstructors.filter(isFloatConstructor)
+                                                     .filter(c => c.BYTES_PER_ELEMENT === 4);
+const float64Constructors = anyTypedArrayConstructors.filter(isFloatConstructor)
+                                                     .filter(c => c.BYTES_PER_ELEMENT === 8);
+
+// Also test with cross-compartment typed arrays.
+const otherGlobal = newGlobal();
+float32Constructors.push(otherGlobal.Float32Array);
+float64Constructors.push(otherGlobal.Float64Array);
+
+function* p(xs, ys) {
+    for (let x of xs) {
+        for (let y of ys) {
+            yield [x, y];
+        }
+    }
+}
+
+const isLittleEndian = new Uint8Array(new Uint16Array([1]).buffer)[0] !== 0;
+
+function geti64(i32, i) {
+    return [i32[2 * i + isLittleEndian], i32[2 * i + !isLittleEndian]];
+}
+
+function seti64(i32, i, [hi, lo]) {
+    i32[i * 2 + isLittleEndian] = hi;
+    i32[i * 2 + !isLittleEndian] = lo;
+}
+
+const NaNs = {
+    Float32: [
+        0x7F800001|0, // smallest SNaN
+        0x7FBFFFFF|0, // largest SNaN
+        0x7FC00000|0, // smallest QNaN
+        0x7FFFFFFF|0, // largest QNaN
+        0xFF800001|0, // smallest SNaN, sign-bit set
+        0xFFBFFFFF|0, // largest SNaN, sign-bit set
+        0xFFC00000|0, // smallest QNaN, sign-bit set
+        0xFFFFFFFF|0, // largest QNaN, sign-bit set
+    ],
+    Float64: [
+        [0x7FF00000|0, 0x00000001|0], // smallest SNaN
+        [0x7FF7FFFF|0, 0xFFFFFFFF|0], // largest SNaN
+        [0x7FF80000|0, 0x00000000|0], // smallest QNaN
+        [0x7FFFFFFF|0, 0xFFFFFFFF|0], // largest QNaN
+        [0xFFF00000|0, 0x00000001|0], // smallest SNaN, sign-bit set
+        [0xFFF7FFFF|0, 0xFFFFFFFF|0], // largest SNaN, sign-bit set
+        [0xFFF80000|0, 0x00000000|0], // smallest QNaN, sign-bit set
+        [0xFFFFFFFF|0, 0xFFFFFFFF|0], // largest QNaN, sign-bit set
+    ],
+};
+
+const cNaN = {
+    Float32: new Int32Array(new Float32Array([NaN]).buffer)[0],
+    Float64: geti64(new Int32Array(new Float64Array([NaN]).buffer), 0),
+};
+
+// Float32 -> Float32
+for (let [sourceConstructor, targetConstructor] of p(float32Constructors, float32Constructors)) {
+    let len = NaNs.Float32.length;
+    let f32 = new sourceConstructor(len);
+    let i32 = new Int32Array(f32.buffer);
+    f32.constructor = targetConstructor;
+
+    for (let i = 0; i < len; ++i) {
+        i32[i] = NaNs.Float32[i];
+    }
+
+    let rf32 = f32.slice(0);
+    let ri32 = new Int32Array(rf32.buffer);
+
+    assertEq(rf32.length, len);
+    assertEq(ri32.length, len);
+
+    // Same bits.
+    for (let i = 0; i < len; ++i) {
+        assertEq(ri32[i], NaNs.Float32[i]);
+    }
+}
+
+// Float32 -> Float64
+for (let [sourceConstructor, targetConstructor] of p(float32Constructors, float64Constructors)) {
+    let len = NaNs.Float32.length;
+    let f32 = new sourceConstructor(len);
+    let i32 = new Int32Array(f32.buffer);
+    f32.constructor = targetConstructor;
+
+    for (let i = 0; i < len; ++i) {
+        i32[i] = NaNs.Float32[i];
+    }
+
+    let rf64 = f32.slice(0);
+    let ri32 = new Int32Array(rf64.buffer);
+
+    assertEq(rf64.length, len);
+    assertEq(ri32.length, 2 * len);
+
+    // NaN bits canonicalized.
+    for (let i = 0; i < len; ++i) {
+        assertEqArray(geti64(ri32, i), cNaN.Float64);
+    }
+}
+
+// Float64 -> Float64
+for (let [sourceConstructor, targetConstructor] of p(float64Constructors, float64Constructors)) {
+    let len = NaNs.Float64.length;
+    let f64 = new sourceConstructor(len);
+    let i32 = new Int32Array(f64.buffer);
+    f64.constructor = targetConstructor;
+
+    for (let i = 0; i < len; ++i) {
+        seti64(i32, i, NaNs.Float64[i]);
+    }
+
+    let rf64 = f64.slice(0);
+    let ri32 = new Int32Array(rf64.buffer);
+
+    assertEq(rf64.length, len);
+    assertEq(ri32.length, 2 * len);
+
+    // Same bits.
+    for (let i = 0; i < len; ++i) {
+        assertEqArray(geti64(ri32, i), NaNs.Float64[i]);
+    }
+}
+
+// Float64 -> Float32
+for (let [sourceConstructor, targetConstructor] of p(float64Constructors, float32Constructors)) {
+    let len = NaNs.Float64.length;
+    let f64 = new sourceConstructor(len);
+    let i32 = new Int32Array(f64.buffer);
+    f64.constructor = targetConstructor;
+
+    for (let i = 0; i < len; ++i) {
+        seti64(i32, i, NaNs.Float64[i]);
+    }
+
+    let rf32 = f64.slice(0);
+    let ri32 = new Int32Array(rf32.buffer);
+
+    assertEq(rf32.length, len);
+    assertEq(ri32.length, len);
+
+    // NaN bits canonicalized.
+    for (let i = 0; i < len; ++i) {
+        assertEqArray(ri32[i], cNaN.Float32);
+    }
+}
+
+if (typeof reportCompare === "function")
+    reportCompare(true, true);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/non262/TypedArray/slice-conversion.js
@@ -0,0 +1,515 @@
+// Test conversions to different element types.
+let tests = [
+    /* Int8Array */
+    {
+        from: Int8Array,
+        to: Int8Array,
+        values: [-129, -128, -127, -1, 0, 1, 127, 128, 129],
+        expected: [127, -128, -127, -1, 0, 1, 127, -128, -127],
+    },
+    {
+        from: Int8Array,
+        to: Uint8Array,
+        values: [-129, -128, -127, -1, 0, 1, 127, 128, 129],
+        expected: [127, 128, 129, 255, 0, 1, 127, 128, 129],
+    },
+    {
+        from: Int8Array,
+        to: Uint8ClampedArray,
+        values: [-129, -128, -127, -1, 0, 1, 127, 128, 129],
+        expected: [127, 0, 0, 0, 0, 1, 127, 0, 0],
+    },
+    {
+        from: Int8Array,
+        to: Int16Array,
+        values: [-129, -128, -127, -1, 0, 1, 127, 128, 129],
+        expected: [127, -128, -127, -1, 0, 1, 127, -128, -127],
+    },
+    {
+        from: Int8Array,
+        to: Uint16Array,
+        values: [-129, -128, -127, -1, 0, 1, 127, 128, 129],
+        expected: [127, 65408, 65409, 65535, 0, 1, 127, 65408, 65409],
+    },
+    {
+        from: Int8Array,
+        to: Int32Array,
+        values: [-129, -128, -127, -1, 0, 1, 127, 128, 129],
+        expected: [127, -128, -127, -1, 0, 1, 127, -128, -127],
+    },
+    {
+        from: Int8Array,
+        to: Uint32Array,
+        values: [-129, -128, -127, -1, 0, 1, 127, 128, 129],
+        expected: [127, 4294967168, 4294967169, 4294967295, 0, 1, 127, 4294967168, 4294967169],
+    },
+    {
+        from: Int8Array,
+        to: Float32Array,
+        values: [-129, -128, -127, -1, 0, 1, 127, 128, 129],
+        expected: [127, -128, -127, -1, 0, 1, 127, -128, -127],
+    },
+    {
+        from: Int8Array,
+        to: Float64Array,
+        values: [-129, -128, -127, -1, 0, 1, 127, 128, 129],
+        expected: [127, -128, -127, -1, 0, 1, 127, -128, -127],
+    },
+
+    /* Uint8Array */
+    {
+        from: Uint8Array,
+        to: Int8Array,
+        values: [0, 1, 127, 128, 129, 254, 255, 256],
+        expected: [0, 1, 127, -128, -127, -2, -1, 0],
+    },
+    {
+        from: Uint8Array,
+        to: Uint8Array,
+        values: [0, 1, 127, 128, 129, 254, 255, 256],
+        expected: [0, 1, 127, 128, 129, 254, 255, 0],
+    },
+    {
+        from: Uint8Array,
+        to: Uint8ClampedArray,
+        values: [0, 1, 127, 128, 129, 254, 255, 256],
+        expected: [0, 1, 127, 128, 129, 254, 255, 0],
+    },
+    {
+        from: Uint8Array,
+        to: Int16Array,
+        values: [0, 1, 127, 128, 129, 254, 255, 256],
+        expected: [0, 1, 127, 128, 129, 254, 255, 0],
+    },
+    {
+        from: Uint8Array,
+        to: Uint16Array,
+        values: [0, 1, 127, 128, 129, 254, 255, 256],
+        expected: [0, 1, 127, 128, 129, 254, 255, 0],
+    },
+    {
+        from: Uint8Array,
+        to: Int32Array,
+        values: [0, 1, 127, 128, 129, 254, 255, 256],
+        expected: [0, 1, 127, 128, 129, 254, 255, 0],
+    },
+    {
+        from: Uint8Array,
+        to: Uint32Array,
+        values: [0, 1, 127, 128, 129, 254, 255, 256],
+        expected: [0, 1, 127, 128, 129, 254, 255, 0],
+    },
+    {
+        from: Uint8Array,
+        to: Float32Array,
+        values: [0, 1, 127, 128, 129, 254, 255, 256],
+        expected: [0, 1, 127, 128, 129, 254, 255, 0],
+    },
+    {
+        from: Uint8Array,
+        to: Float64Array,
+        values: [0, 1, 127, 128, 129, 254, 255, 256],
+        expected: [0, 1, 127, 128, 129, 254, 255, 0],
+    },
+
+    /* Uint8ClampedArray */
+    {
+        from: Uint8ClampedArray,
+        to: Int8Array,
+        values: [0, 1, 127, 128, 129, 254, 255, 256],
+        expected: [0, 1, 127, -128, -127, -2, -1, -1],
+    },
+    {
+        from: Uint8ClampedArray,
+        to: Uint8Array,
+        values: [0, 1, 127, 128, 129, 254, 255, 256],
+        expected: [0, 1, 127, 128, 129, 254, 255, 255],
+    },
+    {
+        from: Uint8ClampedArray,
+        to: Uint8ClampedArray,
+        values: [0, 1, 127, 128, 129, 254, 255, 256],
+        expected: [0, 1, 127, 128, 129, 254, 255, 255],
+    },
+    {
+        from: Uint8ClampedArray,
+        to: Int16Array,
+        values: [0, 1, 127, 128, 129, 254, 255, 256],
+        expected: [0, 1, 127, 128, 129, 254, 255, 255],
+    },
+    {
+        from: Uint8ClampedArray,
+        to: Uint16Array,
+        values: [0, 1, 127, 128, 129, 254, 255, 256],
+        expected: [0, 1, 127, 128, 129, 254, 255, 255],
+    },
+    {
+        from: Uint8ClampedArray,
+        to: Int32Array,
+        values: [0, 1, 127, 128, 129, 254, 255, 256],
+        expected: [0, 1, 127, 128, 129, 254, 255, 255],
+    },
+    {
+        from: Uint8ClampedArray,
+        to: Uint32Array,
+        values: [0, 1, 127, 128, 129, 254, 255, 256],
+        expected: [0, 1, 127, 128, 129, 254, 255, 255],
+    },
+    {
+        from: Uint8ClampedArray,
+        to: Float32Array,
+        values: [0, 1, 127, 128, 129, 254, 255, 256],
+        expected: [0, 1, 127, 128, 129, 254, 255, 255],
+    },
+    {
+        from: Uint8ClampedArray,
+        to: Float64Array,
+        values: [0, 1, 127, 128, 129, 254, 255, 256],
+        expected: [0, 1, 127, 128, 129, 254, 255, 255],
+    },
+
+    /* Int16Array */
+    {
+        from: Int16Array,
+        to: Int8Array,
+        values: [-32769, -32768, -32767, -129, -128, -127, -1, 0, 1, 127, 128, 129, 32767, 32768, 32769],
+        expected: [-1, 0, 1, 127, -128, -127, -1, 0, 1, 127, -128, -127, -1, 0, 1],
+    },
+    {
+        from: Int16Array,
+        to: Uint8Array,
+        values: [-32769, -32768, -32767, -129, -128, -127, -1, 0, 1, 127, 128, 129, 32767, 32768, 32769],
+        expected: [255, 0, 1, 127, 128, 129, 255, 0, 1, 127, 128, 129, 255, 0, 1],
+    },
+    {
+        from: Int16Array,
+        to: Uint8ClampedArray,
+        values: [-32769, -32768, -32767, -129, -128, -127, -1, 0, 1, 127, 128, 129, 32767, 32768, 32769],
+        expected: [255, 0, 0, 0, 0, 0, 0, 0, 1, 127, 128, 129, 255, 0, 0],
+    },
+    {
+        from: Int16Array,
+        to: Int16Array,
+        values: [-32769, -32768, -32767, -129, -128, -127, -1, 0, 1, 127, 128, 129, 32767, 32768, 32769],
+        expected: [32767, -32768, -32767, -129, -128, -127, -1, 0, 1, 127, 128, 129, 32767, -32768, -32767],
+    },
+    {
+        from: Int16Array,
+        to: Uint16Array,
+        values: [-32769, -32768, -32767, -129, -128, -127, -1, 0, 1, 127, 128, 129, 32767, 32768, 32769],
+        expected: [32767, 32768, 32769, 65407, 65408, 65409, 65535, 0, 1, 127, 128, 129, 32767, 32768, 32769],
+    },
+    {
+        from: Int16Array,
+        to: Int32Array,
+        values: [-32769, -32768, -32767, -129, -128, -127, -1, 0, 1, 127, 128, 129, 32767, 32768, 32769],
+        expected: [32767, -32768, -32767, -129, -128, -127, -1, 0, 1, 127, 128, 129, 32767, -32768, -32767],
+    },
+    {
+        from: Int16Array,
+        to: Uint32Array,
+        values: [-32769, -32768, -32767, -129, -128, -127, -1, 0, 1, 127, 128, 129, 32767, 32768, 32769],
+        expected: [32767, 4294934528, 4294934529, 4294967167, 4294967168, 4294967169, 4294967295, 0, 1, 127, 128, 129, 32767, 4294934528, 4294934529],
+    },
+    {
+        from: Int16Array,
+        to: Float32Array,
+        values: [-32769, -32768, -32767, -129, -128, -127, -1, 0, 1, 127, 128, 129, 32767, 32768, 32769],
+        expected: [32767, -32768, -32767, -129, -128, -127, -1, 0, 1, 127, 128, 129, 32767, -32768, -32767],
+    },
+    {
+        from: Int16Array,
+        to: Float64Array,
+        values: [-32769, -32768, -32767, -129, -128, -127, -1, 0, 1, 127, 128, 129, 32767, 32768, 32769],
+        expected: [32767, -32768, -32767, -129, -128, -127, -1, 0, 1, 127, 128, 129, 32767, -32768, -32767],
+    },
+
+    /* Uint16Array */
+    {
+        from: Uint16Array,
+        to: Int8Array,
+        values: [0, 1, 127, 128, 129, 254, 255, 256, 32767, 32768, 32769, 65534, 65535, 65536],
+        expected: [0, 1, 127, -128, -127, -2, -1, 0, -1, 0, 1, -2, -1, 0],
+    },
+    {
+        from: Uint16Array,
+        to: Uint8Array,
+        values: [0, 1, 127, 128, 129, 254, 255, 256, 32767, 32768, 32769, 65534, 65535, 65536],
+        expected: [0, 1, 127, 128, 129, 254, 255, 0, 255, 0, 1, 254, 255, 0],
+    },
+    {
+        from: Uint16Array,
+        to: Uint8ClampedArray,
+        values: [0, 1, 127, 128, 129, 254, 255, 256, 32767, 32768, 32769, 65534, 65535, 65536],
+        expected: [0, 1, 127, 128, 129, 254, 255, 255, 255, 255, 255, 255, 255, 0],
+    },
+    {
+        from: Uint16Array,
+        to: Int16Array,
+        values: [0, 1, 127, 128, 129, 254, 255, 256, 32767, 32768, 32769, 65534, 65535, 65536],
+        expected: [0, 1, 127, 128, 129, 254, 255, 256, 32767, -32768, -32767, -2, -1, 0],
+    },
+    {
+        from: Uint16Array,
+        to: Uint16Array,
+        values: [0, 1, 127, 128, 129, 254, 255, 256, 32767, 32768, 32769, 65534, 65535, 65536],
+        expected: [0, 1, 127, 128, 129, 254, 255, 256, 32767, 32768, 32769, 65534, 65535, 0],
+    },
+    {
+        from: Uint16Array,
+        to: Int32Array,
+        values: [0, 1, 127, 128, 129, 254, 255, 256, 32767, 32768, 32769, 65534, 65535, 65536],
+        expected: [0, 1, 127, 128, 129, 254, 255, 256, 32767, 32768, 32769, 65534, 65535, 0],
+    },
+    {
+        from: Uint16Array,
+        to: Uint32Array,
+        values: [0, 1, 127, 128, 129, 254, 255, 256, 32767, 32768, 32769, 65534, 65535, 65536],
+        expected: [0, 1, 127, 128, 129, 254, 255, 256, 32767, 32768, 32769, 65534, 65535, 0],
+    },
+    {
+        from: Uint16Array,
+        to: Float32Array,
+        values: [0, 1, 127, 128, 129, 254, 255, 256, 32767, 32768, 32769, 65534, 65535, 65536],
+        expected: [0, 1, 127, 128, 129, 254, 255, 256, 32767, 32768, 32769, 65534, 65535, 0],
+    },
+    {
+        from: Uint16Array,
+        to: Float64Array,
+        values: [0, 1, 127, 128, 129, 254, 255, 256, 32767, 32768, 32769, 65534, 65535, 65536],
+        expected: [0, 1, 127, 128, 129, 254, 255, 256, 32767, 32768, 32769, 65534, 65535, 0],
+    },
+
+    /* Int32Array */
+    {
+        from: Int32Array,
+        to: Int8Array,
+        values: [-2147483649, -2147483648, -2147483647, -32769, -32768, -32767, -129, -128, -127, -1, 0, 1, 127, 128, 129, 32767, 32768, 32769, 2147483647, 2147483648, 2147483649],
+        expected: [-1, 0, 1, -1, 0, 1, 127, -128, -127, -1, 0, 1, 127, -128, -127, -1, 0, 1, -1, 0, 1],
+    },
+    {
+        from: Int32Array,
+        to: Uint8Array,
+        values: [-2147483649, -2147483648, -2147483647, -32769, -32768, -32767, -129, -128, -127, -1, 0, 1, 127, 128, 129, 32767, 32768, 32769, 2147483647, 2147483648, 2147483649],
+        expected: [255, 0, 1, 255, 0, 1, 127, 128, 129, 255, 0, 1, 127, 128, 129, 255, 0, 1, 255, 0, 1],
+    },
+    {
+        from: Int32Array,
+        to: Uint8ClampedArray,
+        values: [-2147483649, -2147483648, -2147483647, -32769, -32768, -32767, -129, -128, -127, -1, 0, 1, 127, 128, 129, 32767, 32768, 32769, 2147483647, 2147483648, 2147483649],
+        expected: [255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 127, 128, 129, 255, 255, 255, 255, 0, 0],
+    },
+    {
+        from: Int32Array,
+        to: Int16Array,
+        values: [-2147483649, -2147483648, -2147483647, -32769, -32768, -32767, -129, -128, -127, -1, 0, 1, 127, 128, 129, 32767, 32768, 32769, 2147483647, 2147483648, 2147483649],
+        expected: [-1, 0, 1, 32767, -32768, -32767, -129, -128, -127, -1, 0, 1, 127, 128, 129, 32767, -32768, -32767, -1, 0, 1],
+    },
+    {
+        from: Int32Array,
+        to: Uint16Array,
+        values: [-2147483649, -2147483648, -2147483647, -32769, -32768, -32767, -129, -128, -127, -1, 0, 1, 127, 128, 129, 32767, 32768, 32769, 2147483647, 2147483648, 2147483649],
+        expected: [65535, 0, 1, 32767, 32768, 32769, 65407, 65408, 65409, 65535, 0, 1, 127, 128, 129, 32767, 32768, 32769, 65535, 0, 1],
+    },
+    {
+        from: Int32Array,
+        to: Int32Array,
+        values: [-2147483649, -2147483648, -2147483647, -32769, -32768, -32767, -129, -128, -127, -1, 0, 1, 127, 128, 129, 32767, 32768, 32769, 2147483647, 2147483648, 2147483649],
+        expected: [2147483647, -2147483648, -2147483647, -32769, -32768, -32767, -129, -128, -127, -1, 0, 1, 127, 128, 129, 32767, 32768, 32769, 2147483647, -2147483648, -2147483647],
+    },
+    {
+        from: Int32Array,
+        to: Uint32Array,
+        values: [-2147483649, -2147483648, -2147483647, -32769, -32768, -32767, -129, -128, -127, -1, 0, 1, 127, 128, 129, 32767, 32768, 32769, 2147483647, 2147483648, 2147483649],
+        expected: [2147483647, 2147483648, 2147483649, 4294934527, 4294934528, 4294934529, 4294967167, 4294967168, 4294967169, 4294967295, 0, 1, 127, 128, 129, 32767, 32768, 32769, 2147483647, 2147483648, 2147483649],
+    },
+    {
+        from: Int32Array,
+        to: Float32Array,
+        values: [-2147483649, -2147483648, -2147483647, -32769, -32768, -32767, -129, -128, -127, -1, 0, 1, 127, 128, 129, 32767, 32768, 32769, 2147483647, 2147483648, 2147483649],
+        expected: [2147483648, -2147483648, -2147483648, -32769, -32768, -32767, -129, -128, -127, -1, 0, 1, 127, 128, 129, 32767, 32768, 32769, 2147483648, -2147483648, -2147483648],
+    },
+    {
+        from: Int32Array,
+        to: Float64Array,
+        values: [-2147483649, -2147483648, -2147483647, -32769, -32768, -32767, -129, -128, -127, -1, 0, 1, 127, 128, 129, 32767, 32768, 32769, 2147483647, 2147483648, 2147483649],
+        expected: [2147483647, -2147483648, -2147483647, -32769, -32768, -32767, -129, -128, -127, -1, 0, 1, 127, 128, 129, 32767, 32768, 32769, 2147483647, -2147483648, -2147483647],
+    },
+
+    /* Uint32Array */
+    {
+        from: Uint32Array,
+        to: Int8Array,
+        values: [0, 1, 127, 128, 129, 254, 255, 256, 32767, 32768, 32769, 65534, 65535, 65536, 2147483647, 2147483648, 2147483649, 4294967294, 4294967295, 4294967296],
+        expected: [0, 1, 127, -128, -127, -2, -1, 0, -1, 0, 1, -2, -1, 0, -1, 0, 1, -2, -1, 0],
+    },
+    {
+        from: Uint32Array,
+        to: Uint8Array,
+        values: [0, 1, 127, 128, 129, 254, 255, 256, 32767, 32768, 32769, 65534, 65535, 65536, 2147483647, 2147483648, 2147483649, 4294967294, 4294967295, 4294967296],
+        expected: [0, 1, 127, 128, 129, 254, 255, 0, 255, 0, 1, 254, 255, 0, 255, 0, 1, 254, 255, 0],
+    },
+    {
+        from: Uint32Array,
+        to: Uint8ClampedArray,
+        values: [0, 1, 127, 128, 129, 254, 255, 256, 32767, 32768, 32769, 65534, 65535, 65536, 2147483647, 2147483648, 2147483649, 4294967294, 4294967295, 4294967296],
+        expected: [0, 1, 127, 128, 129, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0],
+    },
+    {
+        from: Uint32Array,
+        to: Int16Array,
+        values: [0, 1, 127, 128, 129, 254, 255, 256, 32767, 32768, 32769, 65534, 65535, 65536, 2147483647, 2147483648, 2147483649, 4294967294, 4294967295, 4294967296],
+        expected: [0, 1, 127, 128, 129, 254, 255, 256, 32767, -32768, -32767, -2, -1, 0, -1, 0, 1, -2, -1, 0],
+    },
+    {
+        from: Uint32Array,
+        to: Uint16Array,
+        values: [0, 1, 127, 128, 129, 254, 255, 256, 32767, 32768, 32769, 65534, 65535, 65536, 2147483647, 2147483648, 2147483649, 4294967294, 4294967295, 4294967296],
+        expected: [0, 1, 127, 128, 129, 254, 255, 256, 32767, 32768, 32769, 65534, 65535, 0, 65535, 0, 1, 65534, 65535, 0],
+    },
+    {
+        from: Uint32Array,
+        to: Int32Array,
+        values: [0, 1, 127, 128, 129, 254, 255, 256, 32767, 32768, 32769, 65534, 65535, 65536, 2147483647, 2147483648, 2147483649, 4294967294, 4294967295, 4294967296],
+        expected: [0, 1, 127, 128, 129, 254, 255, 256, 32767, 32768, 32769, 65534, 65535, 65536, 2147483647, -2147483648, -2147483647, -2, -1, 0],
+    },
+    {
+        from: Uint32Array,
+        to: Uint32Array,
+        values: [0, 1, 127, 128, 129, 254, 255, 256, 32767, 32768, 32769, 65534, 65535, 65536, 2147483647, 2147483648, 2147483649, 4294967294, 4294967295, 4294967296],
+        expected: [0, 1, 127, 128, 129, 254, 255, 256, 32767, 32768, 32769, 65534, 65535, 65536, 2147483647, 2147483648, 2147483649, 4294967294, 4294967295, 0],
+    },
+    {
+        from: Uint32Array,
+        to: Float32Array,
+        values: [0, 1, 127, 128, 129, 254, 255, 256, 32767, 32768, 32769, 65534, 65535, 65536, 2147483647, 2147483648, 2147483649, 4294967294, 4294967295, 4294967296],
+        expected: [0, 1, 127, 128, 129, 254, 255, 256, 32767, 32768, 32769, 65534, 65535, 65536, 2147483648, 2147483648, 2147483648, 4294967296, 4294967296, 0],
+    },
+    {
+        from: Uint32Array,
+        to: Float64Array,
+        values: [0, 1, 127, 128, 129, 254, 255, 256, 32767, 32768, 32769, 65534, 65535, 65536, 2147483647, 2147483648, 2147483649, 4294967294, 4294967295, 4294967296],
+        expected: [0, 1, 127, 128, 129, 254, 255, 256, 32767, 32768, 32769, 65534, 65535, 65536, 2147483647, 2147483648, 2147483649, 4294967294, 4294967295, 0],
+    },
+
+    /* Float32Array */
+    {
+        from: Float32Array,
+        to: Int8Array,
+        values: [-Infinity, -2147483649, -2147483648, -2147483647, -32769, -32768, -32767, -129, -128, -127, -1.6, -1.5, -1.4, -1, -0, 0, 1, 1.4, 1.5, 1.6, 127, 128, 129, 32767, 32768, 32769, 2147483647, 2147483648, 2147483649, Infinity, NaN],
+        expected: [0, 0, 0, 0, -1, 0, 1, 127, -128, -127, -1, -1, -1, -1, 0, 0, 1, 1, 1, 1, 127, -128, -127, -1, 0, 1, 0, 0, 0, 0, 0],
+    },
+    {
+        from: Float32Array,
+        to: Uint8Array,
+        values: [-Infinity, -2147483649, -2147483648, -2147483647, -32769, -32768, -32767, -129, -128, -127, -1.6, -1.5, -1.4, -1, -0, 0, 1, 1.4, 1.5, 1.6, 127, 128, 129, 32767, 32768, 32769, 2147483647, 2147483648, 2147483649, Infinity, NaN],
+        expected: [0, 0, 0, 0, 255, 0, 1, 127, 128, 129, 255, 255, 255, 255, 0, 0, 1, 1, 1, 1, 127, 128, 129, 255, 0, 1, 0, 0, 0, 0, 0],
+    },
+    {
+        from: Float32Array,
+        to: Uint8ClampedArray,
+        values: [-Infinity, -2147483649, -2147483648, -2147483647, -32769, -32768, -32767, -129, -128, -127, -1.6, -1.5, -1.4, -1, -0, 0, 1, 1.4, 1.5, 1.6, 127, 128, 129, 32767, 32768, 32769, 2147483647, 2147483648, 2147483649, Infinity, NaN],
+        expected: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 127, 128, 129, 255, 255, 255, 255, 255, 255, 255, 0],
+    },
+    {
+        from: Float32Array,
+        to: Int16Array,
+        values: [-Infinity, -2147483649, -2147483648, -2147483647, -32769, -32768, -32767, -129, -128, -127, -1.6, -1.5, -1.4, -1, -0, 0, 1, 1.4, 1.5, 1.6, 127, 128, 129, 32767, 32768, 32769, 2147483647, 2147483648, 2147483649, Infinity, NaN],
+        expected: [0, 0, 0, 0, 32767, -32768, -32767, -129, -128, -127, -1, -1, -1, -1, 0, 0, 1, 1, 1, 1, 127, 128, 129, 32767, -32768, -32767, 0, 0, 0, 0, 0],
+    },
+    {
+        from: Float32Array,
+        to: Uint16Array,
+        values: [-Infinity, -2147483649, -2147483648, -2147483647, -32769, -32768, -32767, -129, -128, -127, -1.6, -1.5, -1.4, -1, -0, 0, 1, 1.4, 1.5, 1.6, 127, 128, 129, 32767, 32768, 32769, 2147483647, 2147483648, 2147483649, Infinity, NaN],
+        expected: [0, 0, 0, 0, 32767, 32768, 32769, 65407, 65408, 65409, 65535, 65535, 65535, 65535, 0, 0, 1, 1, 1, 1, 127, 128, 129, 32767, 32768, 32769, 0, 0, 0, 0, 0],
+    },
+    {
+        from: Float32Array,
+        to: Int32Array,
+        values: [-Infinity, -2147483649, -2147483648, -2147483647, -32769, -32768, -32767, -129, -128, -127, -1.6, -1.5, -1.4, -1, -0, 0, 1, 1.4, 1.5, 1.6, 127, 128, 129, 32767, 32768, 32769, 2147483647, 2147483648, 2147483649, Infinity, NaN],
+        expected: [0, -2147483648, -2147483648, -2147483648, -32769, -32768, -32767, -129, -128, -127, -1, -1, -1, -1, 0, 0, 1, 1, 1, 1, 127, 128, 129, 32767, 32768, 32769, -2147483648, -2147483648, -2147483648, 0, 0],
+    },
+    {
+        from: Float32Array,
+        to: Uint32Array,
+        values: [-Infinity, -2147483649, -2147483648, -2147483647, -32769, -32768, -32767, -129, -128, -127, -1.6, -1.5, -1.4, -1, -0, 0, 1, 1.4, 1.5, 1.6, 127, 128, 129, 32767, 32768, 32769, 2147483647, 2147483648, 2147483649, Infinity, NaN],
+        expected: [0, 2147483648, 2147483648, 2147483648, 4294934527, 4294934528, 4294934529, 4294967167, 4294967168, 4294967169, 4294967295, 4294967295, 4294967295, 4294967295, 0, 0, 1, 1, 1, 1, 127, 128, 129, 32767, 32768, 32769, 2147483648, 2147483648, 2147483648, 0, 0],
+    },
+    {
+        from: Float32Array,
+        to: Float32Array,
+        values: [-Infinity, -2147483649, -2147483648, -2147483647, -32769, -32768, -32767, -129, -128, -127, -1.6, -1.5, -1.4, -1, -0, 0, 1, 1.4, 1.5, 1.6, 127, 128, 129, 32767, 32768, 32769, 2147483647, 2147483648, 2147483649, Infinity, NaN],
+        expected: [-Infinity, -2147483648, -2147483648, -2147483648, -32769, -32768, -32767, -129, -128, -127, -1.600000023841858, -1.5, -1.399999976158142, -1, -0, 0, 1, 1.399999976158142, 1.5, 1.600000023841858, 127, 128, 129, 32767, 32768, 32769, 2147483648, 2147483648, 2147483648, Infinity, NaN],
+    },
+    {
+        from: Float32Array,
+        to: Float64Array,
+        values: [-Infinity, -2147483649, -2147483648, -2147483647, -32769, -32768, -32767, -129, -128, -127, -1.6, -1.5, -1.4, -1, -0, 0, 1, 1.4, 1.5, 1.6, 127, 128, 129, 32767, 32768, 32769, 2147483647, 2147483648, 2147483649, Infinity, NaN],
+        expected: [-Infinity, -2147483648, -2147483648, -2147483648, -32769, -32768, -32767, -129, -128, -127, -1.600000023841858, -1.5, -1.399999976158142, -1, -0, 0, 1, 1.399999976158142, 1.5, 1.600000023841858, 127, 128, 129, 32767, 32768, 32769, 2147483648, 2147483648, 2147483648, Infinity, NaN],
+    },
+
+    /* Float64Array */
+    {
+        from: Float64Array,
+        to: Int8Array,
+        values: [-Infinity, -2147483649, -2147483648, -2147483647, -32769, -32768, -32767, -129, -128, -127, -1.6, -1.5, -1.4, -1, -0, 0, 1, 1.4, 1.5, 1.6, 127, 128, 129, 32767, 32768, 32769, 2147483647, 2147483648, 2147483649, Infinity, NaN],
+        expected: [0, -1, 0, 1, -1, 0, 1, 127, -128, -127, -1, -1, -1, -1, 0, 0, 1, 1, 1, 1, 127, -128, -127, -1, 0, 1, -1, 0, 1, 0, 0],
+    },
+    {
+        from: Float64Array,
+        to: Uint8Array,
+        values: [-Infinity, -2147483649, -2147483648, -2147483647, -32769, -32768, -32767, -129, -128, -127, -1.6, -1.5, -1.4, -1, -0, 0, 1, 1.4, 1.5, 1.6, 127, 128, 129, 32767, 32768, 32769, 2147483647, 2147483648, 2147483649, Infinity, NaN],
+        expected: [0, 255, 0, 1, 255, 0, 1, 127, 128, 129, 255, 255, 255, 255, 0, 0, 1, 1, 1, 1, 127, 128, 129, 255, 0, 1, 255, 0, 1, 0, 0],
+    },
+    {
+        from: Float64Array,
+        to: Uint8ClampedArray,
+        values: [-Infinity, -2147483649, -2147483648, -2147483647, -32769, -32768, -32767, -129, -128, -127, -1.6, -1.5, -1.4, -1, -0, 0, 1, 1.4, 1.5, 1.6, 127, 128, 129, 32767, 32768, 32769, 2147483647, 2147483648, 2147483649, Infinity, NaN],
+        expected: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 127, 128, 129, 255, 255, 255, 255, 255, 255, 255, 0],
+    },
+    {
+        from: Float64Array,
+        to: Int16Array,
+        values: [-Infinity, -2147483649, -2147483648, -2147483647, -32769, -32768, -32767, -129, -128, -127, -1.6, -1.5, -1.4, -1, -0, 0, 1, 1.4, 1.5, 1.6, 127, 128, 129, 32767, 32768, 32769, 2147483647, 2147483648, 2147483649, Infinity, NaN],
+        expected: [0, -1, 0, 1, 32767, -32768, -32767, -129, -128, -127, -1, -1, -1, -1, 0, 0, 1, 1, 1, 1, 127, 128, 129, 32767, -32768, -32767, -1, 0, 1, 0, 0],
+    },
+    {
+        from: Float64Array,
+        to: Uint16Array,
+        values: [-Infinity, -2147483649, -2147483648, -2147483647, -32769, -32768, -32767, -129, -128, -127, -1.6, -1.5, -1.4, -1, -0, 0, 1, 1.4, 1.5, 1.6, 127, 128, 129, 32767, 32768, 32769, 2147483647, 2147483648, 2147483649, Infinity, NaN],
+        expected: [0, 65535, 0, 1, 32767, 32768, 32769, 65407, 65408, 65409, 65535, 65535, 65535, 65535, 0, 0, 1, 1, 1, 1, 127, 128, 129, 32767, 32768, 32769, 65535, 0, 1, 0, 0],
+    },
+    {
+        from: Float64Array,
+        to: Int32Array,
+        values: [-Infinity, -2147483649, -2147483648, -2147483647, -32769, -32768, -32767, -129, -128, -127, -1.6, -1.5, -1.4, -1, -0, 0, 1, 1.4, 1.5, 1.6, 127, 128, 129, 32767, 32768, 32769, 2147483647, 2147483648, 2147483649, Infinity, NaN],
+        expected: [0, 2147483647, -2147483648, -2147483647, -32769, -32768, -32767, -129, -128, -127, -1, -1, -1, -1, 0, 0, 1, 1, 1, 1, 127, 128, 129, 32767, 32768, 32769, 2147483647, -2147483648, -2147483647, 0, 0],
+    },
+    {
+        from: Float64Array,
+        to: Uint32Array,
+        values: [-Infinity, -2147483649, -2147483648, -2147483647, -32769, -32768, -32767, -129, -128, -127, -1.6, -1.5, -1.4, -1, -0, 0, 1, 1.4, 1.5, 1.6, 127, 128, 129, 32767, 32768, 32769, 2147483647, 2147483648, 2147483649, Infinity, NaN],
+        expected: [0, 2147483647, 2147483648, 2147483649, 4294934527, 4294934528, 4294934529, 4294967167, 4294967168, 4294967169, 4294967295, 4294967295, 4294967295, 4294967295, 0, 0, 1, 1, 1, 1, 127, 128, 129, 32767, 32768, 32769, 2147483647, 2147483648, 2147483649, 0, 0],
+    },
+    {
+        from: Float64Array,
+        to: Float32Array,
+        values: [-Infinity, -2147483649, -2147483648, -2147483647, -32769, -32768, -32767, -129, -128, -127, -1.6, -1.5, -1.4, -1, -0, 0, 1, 1.4, 1.5, 1.6, 127, 128, 129, 32767, 32768, 32769, 2147483647, 2147483648, 2147483649, Infinity, NaN],
+        expected: [-Infinity, -2147483648, -2147483648, -2147483648, -32769, -32768, -32767, -129, -128, -127, -1.600000023841858, -1.5, -1.399999976158142, -1, -0, 0, 1, 1.399999976158142, 1.5, 1.600000023841858, 127, 128, 129, 32767, 32768, 32769, 2147483648, 2147483648, 2147483648, Infinity, NaN],
+    },
+    {
+        from: Float64Array,
+        to: Float64Array,
+        values: [-Infinity, -2147483649, -2147483648, -2147483647, -32769, -32768, -32767, -129, -128, -127, -1.6, -1.5, -1.4, -1, -0, 0, 1, 1.4, 1.5, 1.6, 127, 128, 129, 32767, 32768, 32769, 2147483647, 2147483648, 2147483649, Infinity, NaN],
+        expected: [-Infinity, -2147483649, -2147483648, -2147483647, -32769, -32768, -32767, -129, -128, -127, -1.6, -1.5, -1.4, -1, -0, 0, 1, 1.4, 1.5, 1.6, 127, 128, 129, 32767, 32768, 32769, 2147483647, 2147483648, 2147483649, Infinity, NaN],
+    },
+];
+
+for (let {from, to, values, expected} of tests) {
+    let ta = new from(values);
+    ta.constructor = to;
+    assertEqArray(ta.slice(0), expected, `${from.name} -> ${to.name}`);
+}
+
+if (typeof reportCompare === "function")
+    reportCompare(true, true);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/non262/TypedArray/slice-memcpy.js
@@ -0,0 +1,84 @@
+const otherGlobal = newGlobal();
+
+// Create with new ArrayBuffer and offset.
+for (var constructor of typedArrayConstructors) {
+    const elementSize = constructor.BYTES_PER_ELEMENT;
+    let ab = new constructor(10).map((v, i) => i).buffer;
+    let ta = new constructor(ab, 2 * elementSize, 6);
+    ta.constructor = {
+        [Symbol.species]: function(len) {
+            return new constructor(new ArrayBuffer((len + 4) * elementSize), 4 * elementSize);
+        }
+    };
+    let tb = ta.slice(0);
+
+    assertEqArray(ta, [2, 3, 4, 5, 6, 7]);
+    assertEqArray(tb, [2, 3, 4, 5, 6, 7]);
+}
+
+// Source and target arrays use the same ArrayBuffer, target range before source range.
+for (var constructor of typedArrayConstructors) {
+    const elementSize = constructor.BYTES_PER_ELEMENT;
+    let ab = new constructor(10).map((v, i) => i).buffer;
+    let ta = new constructor(ab, 2 * elementSize, 6);
+    ta.constructor = {
+        [Symbol.species]: function(len) {
+            return new constructor(ab, 0, len);
+        }
+    };
+    let tb = ta.slice(0);
+
+    assertEqArray(ta, [4, 5, 6, 7, 6, 7]);
+    assertEqArray(tb, [2, 3, 4, 5, 6, 7]);
+    assertEqArray(new constructor(ab), [2, 3, 4, 5, 6, 7, 6, 7, 8, 9]);
+}
+
+// Source and target arrays use the same ArrayBuffer, target range after source range.
+for (var constructor of typedArrayConstructors) {
+    const elementSize = constructor.BYTES_PER_ELEMENT;
+    let ab = new constructor(10).map((v, i) => i + 1).buffer;
+    let ta = new constructor(ab, 0, 6);
+    ta.constructor = {
+        [Symbol.species]: function(len) {
+            return new constructor(ab, 2 * elementSize, len);
+        }
+    };
+    let tb = ta.slice(0);
+
+    assertEqArray(ta, [1, 2, 1, 2, 1, 2]);
+    assertEqArray(tb, [1, 2, 1, 2, 1, 2]);
+    assertEqArray(new constructor(ab), [1, 2, 1, 2, 1, 2, 1, 2, 9, 10]);
+}
+
+// Tricky: Same as above, but with SharedArrayBuffer and different compartments.
+if (typeof setSharedArrayBuffer === "function") {
+    for (var constructor of typedArrayConstructors) {
+        const elementSize = constructor.BYTES_PER_ELEMENT;
+        let ts = new constructor(new SharedArrayBuffer(10 * elementSize));
+        for (let i = 0; i < ts.length; i++) {
+            ts[i] = i + 1;
+        }
+        let ab = ts.buffer;
+        let ta = new constructor(ab, 0, 6);
+        ta.constructor = {
+            [Symbol.species]: function(len) {
+                setSharedArrayBuffer(ab);
+                try {
+                    return otherGlobal.eval(`
+                        new ${constructor.name}(getSharedArrayBuffer(), ${2 * elementSize}, ${len});
+                    `);
+                } finally {
+                    setSharedArrayBuffer(null);
+                }
+            }
+        };
+        let tb = ta.slice(0);
+
+        assertEqArray(ta, [1, 2, 1, 2, 1, 2]);
+        assertEqArray(tb, [1, 2, 1, 2, 1, 2]);
+        assertEqArray(new constructor(ab), [1, 2, 1, 2, 1, 2, 1, 2, 9, 10]);
+    }
+}
+
+if (typeof reportCompare === "function")
+    reportCompare(true, true);
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -1247,18 +1247,23 @@ intrinsic_MoveTypedArrayElements(JSConte
 // If calling code discipline ever fails to be maintained, it's gonna have a
 // bad time.
 static TypedArrayObject*
 DangerouslyUnwrapTypedArray(JSContext* cx, JSObject* obj)
 {
     // An unwrapped pointer to an object potentially on the other side of a
     // compartment boundary!  Isn't this such fun?
     JSObject* unwrapped = CheckedUnwrap(obj);
+    if (!unwrapped) {
+        ReportAccessDenied(cx);
+        return nullptr;
+    }
+
     if (!unwrapped->is<TypedArrayObject>()) {
-        // By *appearances* this can't happen, as self-hosted TypedArraySet
+        // By *appearances* this can't happen, as self-hosted code
         // checked this.  But.  Who's to say a GC couldn't happen between
         // the check that this value was a typed array, and this extraction
         // occurring?  A GC might turn a cross-compartment wrapper |obj| into
         // |unwrapped == obj|, a dead object no longer connected its typed
         // array.
         //
         // Yeah, yeah, it's pretty unlikely.  Are you willing to stake a
         // sec-critical bug on that assessment, now and forever, against
@@ -1583,16 +1588,123 @@ intrinsic_SetOverlappingTypedElements(JS
 
     CopyToDisjointArray(target, targetOffset, SharedMem<void*>::unshared(copyOfSrcData.get()),
                         unsafeSrcTypeCrossCompartment, count);
 
     args.rval().setUndefined();
     return true;
 }
 
+// The specification requires us to perform bitwise copying when |sourceType|
+// and |targetType| are the same (ES2017, ยง22.2.3.24, step 15). Additionally,
+// as an optimization, we can also perform bitwise copying when |sourceType|
+// and |targetType| have compatible bit-level representations.
+static bool
+IsTypedArrayBitwiseSlice(Scalar::Type sourceType, Scalar::Type targetType)
+{
+    switch (sourceType) {
+      case Scalar::Int8:
+        return targetType == Scalar::Int8 || targetType == Scalar::Uint8;
+
+      case Scalar::Uint8:
+      case Scalar::Uint8Clamped:
+        return targetType == Scalar::Int8 || targetType == Scalar::Uint8 ||
+               targetType == Scalar::Uint8Clamped;
+
+      case Scalar::Int16:
+      case Scalar::Uint16:
+        return targetType == Scalar::Int16 || targetType == Scalar::Uint16;
+
+      case Scalar::Int32:
+      case Scalar::Uint32:
+        return targetType == Scalar::Int32 || targetType == Scalar::Uint32;
+
+      case Scalar::Float32:
+        return targetType == Scalar::Float32;
+
+      case Scalar::Float64:
+        return targetType == Scalar::Float64;
+
+      default:
+        MOZ_CRASH("IsTypedArrayBitwiseSlice with a bogus typed array type");
+    }
+}
+
+static bool
+intrinsic_TypedArrayBitwiseSlice(JSContext* cx, unsigned argc, Value* vp)
+{
+    CallArgs args = CallArgsFromVp(argc, vp);
+    MOZ_ASSERT(args.length() == 4);
+    MOZ_ASSERT(args[0].isObject());
+    MOZ_ASSERT(args[1].isObject());
+    MOZ_ASSERT(args[2].isInt32());
+    MOZ_ASSERT(args[3].isInt32());
+
+    Rooted<TypedArrayObject*> source(cx, &args[0].toObject().as<TypedArrayObject>());
+    MOZ_ASSERT(!source->hasDetachedBuffer());
+
+    // As directed by |DangerouslyUnwrapTypedArray|, sigil this pointer and all
+    // variables derived from it to counsel extreme caution here.
+    Rooted<TypedArrayObject*> unsafeTypedArrayCrossCompartment(cx);
+    unsafeTypedArrayCrossCompartment = DangerouslyUnwrapTypedArray(cx, &args[1].toObject());
+    if (!unsafeTypedArrayCrossCompartment)
+        return false;
+    MOZ_ASSERT(!unsafeTypedArrayCrossCompartment->hasDetachedBuffer());
+
+    Scalar::Type sourceType = source->type();
+    if (!IsTypedArrayBitwiseSlice(sourceType, unsafeTypedArrayCrossCompartment->type())) {
+        args.rval().setBoolean(false);
+        return true;
+    }
+
+    MOZ_ASSERT(args[2].toInt32() >= 0);
+    uint32_t sourceOffset = uint32_t(args[2].toInt32());
+
+    MOZ_ASSERT(args[3].toInt32() >= 0);
+    uint32_t count = uint32_t(args[3].toInt32());
+
+    MOZ_ASSERT(count > 0 && count <= source->length());
+    MOZ_ASSERT(sourceOffset <= source->length() - count);
+    MOZ_ASSERT(count <= unsafeTypedArrayCrossCompartment->length());
+
+    size_t elementSize = TypedArrayElemSize(sourceType);
+    MOZ_ASSERT(elementSize == TypedArrayElemSize(unsafeTypedArrayCrossCompartment->type()));
+
+    SharedMem<uint8_t*> sourceData =
+        source->viewDataEither().cast<uint8_t*>() + sourceOffset * elementSize;
+
+    SharedMem<uint8_t*> unsafeTargetDataCrossCompartment =
+        unsafeTypedArrayCrossCompartment->viewDataEither().cast<uint8_t*>();
+
+    uint32_t byteLength = count * elementSize;
+
+    // The same-type case requires exact copying preserving the bit-level
+    // encoding of the source data, so use memcpy if possible. If source and
+    // target are the same buffer, we can't use memcpy (or memmove), because
+    // the specification requires sequential copying of the values. This case
+    // is only possible if a @@species constructor created a specifically
+    // crafted typed array. It won't happen in normal code and hence doesn't
+    // need to be optimized.
+    if (!TypedArrayObject::sameBuffer(source, unsafeTypedArrayCrossCompartment)) {
+        jit::AtomicOperations::memcpySafeWhenRacy(unsafeTargetDataCrossCompartment,
+                                                  sourceData,
+                                                  byteLength);
+    } else {
+        using namespace jit;
+
+        for (; byteLength > 0; byteLength--) {
+            AtomicOperations::storeSafeWhenRacy(unsafeTargetDataCrossCompartment++,
+                                                AtomicOperations::loadSafeWhenRacy(sourceData++));
+        }
+    }
+
+    args.rval().setBoolean(true);
+    return true;
+}
+
 static bool
 intrinsic_RegExpCreate(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
 
     MOZ_ASSERT(args.length() == 1 || args.length() == 2);
     MOZ_ASSERT_IF(args.length() == 2, args[1].isString() || args[1].isUndefined());
     MOZ_ASSERT(!args.isConstructing());
@@ -2468,16 +2580,18 @@ static const JSFunctionSpec intrinsic_fu
 
     JS_FN("MoveTypedArrayElements",  intrinsic_MoveTypedArrayElements,  4,0),
     JS_FN("SetFromTypedArrayApproach",intrinsic_SetFromTypedArrayApproach, 4, 0),
     JS_FN("SetOverlappingTypedElements",intrinsic_SetOverlappingTypedElements,3,0),
 
     JS_INLINABLE_FN("SetDisjointTypedElements",intrinsic_SetDisjointTypedElements,3,0,
                     IntrinsicSetDisjointTypedElements),
 
+    JS_FN("TypedArrayBitwiseSlice", intrinsic_TypedArrayBitwiseSlice, 4, 0),
+
     JS_FN("CallArrayBufferMethodIfWrapped",
           CallNonGenericSelfhostedMethod<Is<ArrayBufferObject>>, 2, 0),
     JS_FN("CallSharedArrayBufferMethodIfWrapped",
           CallNonGenericSelfhostedMethod<Is<SharedArrayBufferObject>>, 2, 0),
     JS_FN("CallTypedArrayMethodIfWrapped",
           CallNonGenericSelfhostedMethod<Is<TypedArrayObject>>, 2, 0),
 
     JS_FN("CallGeneratorMethodIfWrapped",
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -4508,17 +4508,17 @@ pref("toolkit.zoomManager.zoomValues", "
 
 //
 // Image-related prefs
 //
 
 // The maximum size (in kB) that the aggregate frames of an animation can use
 // before it starts to discard already displayed frames and redecode them as
 // necessary.
-pref("image.animated.decode-on-demand.threshold-kb", 20480);
+pref("image.animated.decode-on-demand.threshold-kb", 4194303);
 
 // The minimum number of frames we want to have buffered ahead of an
 // animation's currently displayed frame.
 pref("image.animated.decode-on-demand.batch-size", 6);
 
 // Maximum number of surfaces for an image before entering "factor of 2" mode.
 // This in addition to the number of "native" sizes of an image. A native size
 // is a size for which we can decode a frame without up or downscaling. Most
--- a/taskcluster/ci/l10n/kind.yml
+++ b/taskcluster/ci/l10n/kind.yml
@@ -63,17 +63,17 @@ job-template:
          android-api-16-l10n: internal
          macosx64-nightly: internal
    worker-type:
       by-build-platform:
          default: aws-provisioner-v1/gecko-{level}-b-linux
          android: aws-provisioner-v1/gecko-{level}-b-android
    treeherder:
       symbol: L10n
-      tier: 2
+      tier: 3
       platform:
          by-build-platform:
             linux64-l10n: linux64/opt
             linux-l10n: linux32/opt
             macosx64: osx-cross/opt
             android-api-16-l10n: android-4-0-armv7-api16/opt
    mozharness:
       config:
--- a/taskcluster/ci/release-beetmover-signed-langpacks/kind.yml
+++ b/taskcluster/ci/release-beetmover-signed-langpacks/kind.yml
@@ -21,9 +21,8 @@ job-template:
    worker-type:
       by-project:
          mozilla-beta: scriptworker-prov-v1/beetmoverworker-v1
          mozilla-release: scriptworker-prov-v1/beetmoverworker-v1
          mozilla-esr60: scriptworker-prov-v1/beetmoverworker-v1
          default: scriptworker-prov-v1/beetmoverworker-dev
    run-on-projects: []
    shipping-phase: promote
-   shipping-product: firefox
--- a/taskcluster/ci/release-sign-and-push-langpacks/kind.yml
+++ b/taskcluster/ci/release-sign-and-push-langpacks/kind.yml
@@ -11,18 +11,19 @@ transforms:
 
 kind-dependencies:
    - build
    - nightly-l10n
 
 
 only-for-build-platforms:
    - linux64-nightly/opt    # addons.mozilla.org only support 1 platform per locale. That's why we use linux64
+   - linux64-devedition-nightly/opt
    - macosx64-nightly/opt   # Although, we need the special locale "ja-JP-Mac" from this platform
-   # TODO Activate devedition
+   - macosx64-devedition-nightly/opt
 
 
 job-template:
    description: Signs {locales} XPIs for platform via addons.mozilla.org and pushes them
    worker-type:
       by-project:
          mozilla-beta: scriptworker-prov-v1/addon-v1
          mozilla-release: scriptworker-prov-v1/addon-v1
@@ -43,9 +44,8 @@ job-template:
             - project:releng:addons.mozilla.org:server:production
          mozilla-release:
             - project:releng:addons.mozilla.org:server:production
          mozilla-esr60:
             - project:releng:addons.mozilla.org:server:production
          default:
             - project:releng:addons.mozilla.org:server:staging
    shipping-phase: promote
-   shipping-product: firefox
--- a/taskcluster/taskgraph/transforms/beetmover_repackage.py
+++ b/taskcluster/taskgraph/transforms/beetmover_repackage.py
@@ -58,52 +58,33 @@ logger = logging.getLogger(__name__)
     "mozharness.zip",
 ]
 
 # Until bug 1331141 is fixed, if you are adding any new artifacts here that
 # need to be transfered to S3, please be aware you also need to follow-up
 # with a beetmover patch in https://github.com/mozilla-releng/beetmoverscript/.
 # See example in bug 1348286
 UPSTREAM_ARTIFACT_UNSIGNED_PATHS = {
-    r'^(linux(|64)|macosx64)-nightly$':
+    r'^(linux(|64)|macosx64)(|-devedition)-nightly$':
         _DESKTOP_UPSTREAM_ARTIFACTS_UNSIGNED_EN_US + [
             'host/bin/mar',
             'host/bin/mbsdiff',
         ],
-    r'^(linux(|64)|macosx64)-devedition-nightly$':
-        _DESKTOP_UPSTREAM_ARTIFACTS_UNSIGNED_EN_US + [
-            'host/bin/mar',
-            'host/bin/mbsdiff',
-            # TODO Bug 1453033: Sign devedition langpacks
-            'target.langpack.xpi',
-        ],
     r'^linux64-asan-reporter-nightly$':
         filter(lambda a: a not in ('target.crashreporter-symbols.zip', 'target.jsshell.zip'),
                _DESKTOP_UPSTREAM_ARTIFACTS_UNSIGNED_EN_US + [
                     "host/bin/mar",
                     "host/bin/mbsdiff",
                 ]),
-    r'^win(32|64)-nightly$':
+    r'^win(32|64)(|-devedition)-nightly$':
         _DESKTOP_UPSTREAM_ARTIFACTS_UNSIGNED_EN_US + [
             'host/bin/mar.exe',
             'host/bin/mbsdiff.exe',
         ],
-    r'^win(32|64)-devedition-nightly$':
-        _DESKTOP_UPSTREAM_ARTIFACTS_UNSIGNED_EN_US + [
-            'host/bin/mar.exe',
-            'host/bin/mbsdiff.exe',
-            # TODO Bug 1453033: Sign devedition langpacks
-            'target.langpack.xpi',
-        ],
-    r'^(linux(|64)|macosx64|win(32|64))-nightly-l10n$': [],
-    r'^(linux(|64)|macosx64|win(32|64))-devedition-nightly-l10n$':
-        [
-            # TODO Bug 1453033: Sign devedition langpacks
-            'target.langpack.xpi',
-        ],
+    r'^(linux(|64)|macosx64|win(32|64))(|-devedition)-nightly-l10n$': [],
 }
 
 # Until bug 1331141 is fixed, if you are adding any new artifacts here that
 # need to be transfered to S3, please be aware you also need to follow-up
 # with a beetmover patch in https://github.com/mozilla-releng/beetmoverscript/.
 # See example in bug 1348286
 UPSTREAM_ARTIFACT_SIGNED_PATHS = {
     r'^linux(|64)(|-devedition|-asan-reporter)-nightly(|-l10n)$':
--- a/taskcluster/taskgraph/transforms/release_beetmover_signed_addons.py
+++ b/taskcluster/taskgraph/transforms/release_beetmover_signed_addons.py
@@ -166,19 +166,23 @@ def strip_unused_data(config, jobs):
 def yield_all_platform_jobs(config, jobs):
     # Even though langpacks are now platform independent, we keep beetmoving them at old
     # platform-specific locations. That's why this transform exist
     for job in jobs:
         if 'ja-JP-mac' in job['label']:
             # This locale must not be copied on any other platform than macos
             yield job
         else:
-            for platform in ('linux', 'linux64', 'macosx64', 'win32', 'win64'):
+            platforms = ('linux', 'linux64', 'macosx64', 'win32', 'win64')
+            if 'devedition' in job['attributes']['build_platform']:
+                platforms = ('{}-devedition'.format(plat) for plat in platforms)
+            for platform in platforms:
                 platform_job = copy.deepcopy(job)
-                if 'ja' in platform_job['attributes']['chunk_locales'] and platform == 'macosx64':
+                if 'ja' in platform_job['attributes']['chunk_locales'] and \
+                        platform in ('macosx64', 'macosx64-devedition'):
                     platform_job = _strip_ja_data_from_linux_job(platform_job)
 
                 platform_job = _change_platform_data(platform_job, platform)
 
                 yield platform_job
 
 
 def _strip_ja_data_from_linux_job(platform_job):
@@ -192,17 +196,20 @@ def _strip_ja_data_from_linux_job(platfo
         for artifact in platform_job['worker']['upstream-artifacts']
         if artifact['locale'] != 'ja'
     ]
 
     return platform_job
 
 
 def _change_platform_data(platform_job, platform):
+    orig_platform = 'linux64'
+    if 'devedition' in platform:
+        orig_platform = 'linux64-devedition'
     platform_job['attributes']['build_platform'] = platform
-    platform_job['label'] = platform_job['label'].replace('linux64', platform)
-    platform_job['description'] = platform_job['description'].replace('linux64', platform)
+    platform_job['label'] = platform_job['label'].replace(orig_platform, platform)
+    platform_job['description'] = platform_job['description'].replace(orig_platform, platform)
     platform_job['treeherder']['platform'] = platform_job['treeherder']['platform'].replace(
-        'linux64', platform
+        orig_platform, platform
     )
     platform_job['worker']['release-properties']['platform'] = platform
 
     return platform_job
--- a/taskcluster/taskgraph/transforms/release_sign_and_push_langpacks.py
+++ b/taskcluster/taskgraph/transforms/release_sign_and_push_langpacks.py
@@ -85,19 +85,19 @@ def copy_attributes(config, jobs):
         yield job
 
 
 @transforms.add
 def filter_out_macos_jobs_but_mac_only_locales(config, jobs):
     for job in jobs:
         build_platform = job['dependent-task'].attributes.get('build_platform')
 
-        if build_platform == 'linux64-nightly':
+        if build_platform in ('linux64-nightly', 'linux64-devedition-nightly'):
             yield job
-        elif build_platform == 'macosx64-nightly' and \
+        elif build_platform in ('macosx64-nightly', 'macosx64-devedition-nightly') and \
                 'ja-JP-mac' in job['attributes']['chunk_locales']:
             # Other locales of the same job shouldn't be processed
             job['attributes']['chunk_locales'] = ['ja-JP-mac']
             job['label'] = job['label'].replace(
                 job['attributes']['l10n_chunk'], 'ja-JP-mac'
             )
             yield job