Bug 1256945 - Coerce SIMD lane indexes with ToNumber(). r=bbouvier
authorJakob Stoklund Olesen <jolesen@mozilla.com>
Wed, 16 Mar 2016 10:15:35 -0700
changeset 341373 26242740f9805048f2c17cc801f256ce843ad155
parent 341372 5659ed97095ea8ccf168fcc72b7e3980318aec95
child 341374 5cb9d1e18724a6edea730b395dd14e147a40ea4a
push id13203
push userdmitchell@mozilla.com
push dateWed, 16 Mar 2016 22:40:30 +0000
reviewersbbouvier
bugs1256945
milestone48.0a1
Bug 1256945 - Coerce SIMD lane indexes with ToNumber(). r=bbouvier The SIMDToLane() function in the SIMD.js specification uses ToNumber() to coerce lane index arguments to a number before checking the the index is an integer in range. Add an ArgumentToLaneIndex() function to SIMD.cpp that implements the same semantics. This function throws a RangeError if the coerced argument is not integral or out of range. Update tests to match the new semantics. The differences are: - More values are accepted as lane indexes (null, true, false, "5.0", ...). - A TypeError is only thrown if ToNumber fails. If the argument can be coerced to a number, a RangeError is thrown if other checks fail. Fix the testShuffleForType() test in ests/ecma_7/SIMD/swizzle-shuffle.js which should have been calling `shuffle` but was calling `swizzle`. MozReview-Commit-ID: 7w5KhWwKmeF
js/src/builtin/SIMD.cpp
js/src/jit-test/tests/SIMD/replacelane.js
js/src/jit-test/tests/SIMD/shuffle.js
js/src/jit-test/tests/SIMD/swizzle.js
js/src/tests/ecma_7/SIMD/replaceLane.js
js/src/tests/ecma_7/SIMD/swizzle-shuffle.js
js/src/tests/ecma_7/SIMD/typedobjects.js
--- a/js/src/builtin/SIMD.cpp
+++ b/js/src/builtin/SIMD.cpp
@@ -34,16 +34,18 @@ using mozilla::IsNaN;
 using mozilla::FloorLog2;
 using mozilla::NumberIsInt32;
 
 ///////////////////////////////////////////////////////////////////////////
 // SIMD
 
 static_assert(unsigned(SimdType::Count) == 12, "sync with TypedObjectConstants.h");
 
+static bool ArgumentToLaneIndex(JSContext* cx, JS::HandleValue v, unsigned limit, unsigned* lane);
+
 static bool
 CheckVectorObject(HandleValue v, SimdType expectedType)
 {
     if (!v.isObject())
         return false;
 
     JSObject& obj = v.toObject();
     if (!obj.is<TypedObject>())
@@ -138,16 +140,23 @@ ErrorWrongTypeArg(JSContext* cx, size_t 
         return false;
 
     JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_SIMD_NOT_A_VECTOR,
                          typeNameStr, charArgIndex);
     JS_free(cx, typeNameStr);
     return false;
 }
 
+static inline bool
+ErrorBadIndex(JSContext* cx)
+{
+    JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_BAD_INDEX);
+    return false;
+}
+
 template<typename T>
 static SimdTypeDescr*
 GetTypeDescr(JSContext* cx)
 {
     RootedGlobalObject global(cx, cx->global());
     return GlobalObject::getOrCreateSimdTypeDescr(cx, global, T::type);
 }
 
@@ -849,24 +858,22 @@ BinaryFunc(JSContext* cx, unsigned argc,
 
 template<typename V>
 static bool
 ExtractLane(JSContext* cx, unsigned argc, Value* vp)
 {
     typedef typename V::Elem Elem;
 
     CallArgs args = CallArgsFromVp(argc, vp);
-    if (args.length() < 2 || !IsVectorObject<V>(args[0]) || !args[1].isNumber())
+    if (args.length() < 2 || !IsVectorObject<V>(args[0]))
         return ErrorBadArgs(cx);
 
-    int32_t lane;
-    if (!NumberIsInt32(args[1].toNumber(), &lane))
-        return ErrorBadArgs(cx);
-    if (lane < 0 || uint32_t(lane) >= V::lanes)
-        return ErrorBadArgs(cx);
+    unsigned lane;
+    if (!ArgumentToLaneIndex(cx, args[1], V::lanes, &lane))
+        return false;
 
     Elem* vec = TypedObjectMemory<Elem*>(args[0]);
     Elem val = vec[lane];
     args.rval().set(V::ToValue(val));
     return true;
 }
 
 template<typename V>
@@ -916,22 +923,19 @@ ReplaceLane(JSContext* cx, unsigned argc
     CallArgs args = CallArgsFromVp(argc, vp);
     // Only the first and second arguments are mandatory
     if (args.length() < 2 || !IsVectorObject<V>(args[0]))
         return ErrorBadArgs(cx);
 
     Elem* vec = TypedObjectMemory<Elem*>(args[0]);
     Elem result[V::lanes];
 
-    int32_t lanearg;
-    if (!args[1].isNumber() || !NumberIsInt32(args[1].toNumber(), &lanearg))
-        return ErrorBadArgs(cx);
-    if (lanearg < 0 || uint32_t(lanearg) >= V::lanes)
-        return ErrorBadArgs(cx);
-    uint32_t lane = uint32_t(lanearg);
+    unsigned lane;
+    if (!ArgumentToLaneIndex(cx, args[1], V::lanes, &lane))
+        return false;
 
     Elem value;
     if (!V::Cast(cx, args.get(2), &value))
         return false;
 
     for (unsigned i = 0; i < V::lanes; i++)
         result[i] = i == lane ? value : vec[i];
     return StoreResult<V>(cx, args, result);
@@ -942,24 +946,20 @@ static bool
 Swizzle(JSContext* cx, unsigned argc, Value* vp)
 {
     typedef typename V::Elem Elem;
 
     CallArgs args = CallArgsFromVp(argc, vp);
     if (args.length() != (V::lanes + 1) || !IsVectorObject<V>(args[0]))
         return ErrorBadArgs(cx);
 
-    uint32_t lanes[V::lanes];
+    unsigned lanes[V::lanes];
     for (unsigned i = 0; i < V::lanes; i++) {
-        int32_t lane;
-        if (!args[i + 1].isNumber() || !NumberIsInt32(args[i + 1].toNumber(), &lane))
-            return ErrorBadArgs(cx);
-        if (lane < 0 || uint32_t(lane) >= V::lanes)
-            return ErrorBadArgs(cx);
-        lanes[i] = uint32_t(lane);
+        if (!ArgumentToLaneIndex(cx, args[i + 1], V::lanes, &lanes[i]))
+            return false;
     }
 
     Elem* val = TypedObjectMemory<Elem*>(args[0]);
 
     Elem result[V::lanes];
     for (unsigned i = 0; i < V::lanes; i++)
         result[i] = val[lanes[i]];
 
@@ -971,24 +971,20 @@ static bool
 Shuffle(JSContext* cx, unsigned argc, Value* vp)
 {
     typedef typename V::Elem Elem;
 
     CallArgs args = CallArgsFromVp(argc, vp);
     if (args.length() != (V::lanes + 2) || !IsVectorObject<V>(args[0]) || !IsVectorObject<V>(args[1]))
         return ErrorBadArgs(cx);
 
-    uint32_t lanes[V::lanes];
+    unsigned lanes[V::lanes];
     for (unsigned i = 0; i < V::lanes; i++) {
-        int32_t lane;
-        if (!args[i + 2].isNumber() || !NumberIsInt32(args[i + 2].toNumber(), &lane))
-            return ErrorBadArgs(cx);
-        if (lane < 0 || uint32_t(lane) >= (2 * V::lanes))
-            return ErrorBadArgs(cx);
-        lanes[i] = uint32_t(lane);
+        if (!ArgumentToLaneIndex(cx, args[i + 2], 2 * V::lanes, &lanes[i]))
+            return false;
     }
 
     Elem* lhs = TypedObjectMemory<Elem*>(args[0]);
     Elem* rhs = TypedObjectMemory<Elem*>(args[1]);
 
     Elem result[V::lanes];
     for (unsigned i = 0; i < V::lanes; i++) {
         Elem* selectedInput = lanes[i] < V::lanes ? lhs : rhs;
@@ -1303,34 +1299,46 @@ ArgumentToIntegerIndex(JSContext* cx, JS
     // floating point numbers end at 2^53, so make that our upper limit. If we
     // ever support arrays with more than 2^53 elements, this will need to
     // change.
     //
     // Reject infinities, NaNs, and numbers outside the contiguous integer range
     // with a RangeError.
 
     // Write relation so NaNs throw a RangeError.
-    if (!(0 <= d && d <= (uint64_t(1) << 53))) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_BAD_INDEX);
-        return false;
-    }
+    if (!(0 <= d && d <= (uint64_t(1) << 53)))
+        return ErrorBadIndex(cx);
 
     // Check that d is an integer, throw a RangeError if not.
     // Note that this conversion could invoke undefined behaviour without the
     // range check above.
     uint64_t i(d);
-    if (d != double(i)) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_BAD_INDEX);
-        return false;
-    }
+    if (d != double(i))
+        return ErrorBadIndex(cx);
 
     *index = i;
     return true;
 }
 
+// Extract an integer lane index from a function argument.
+//
+// Register an exception and return false if the argument is not suitable.
+static bool
+ArgumentToLaneIndex(JSContext* cx, JS::HandleValue v, unsigned limit, unsigned* lane)
+{
+    uint64_t arg;
+    if (!ArgumentToIntegerIndex(cx, v, &arg))
+        return false;
+    if (arg >= limit)
+        return ErrorBadIndex(cx);
+
+    *lane = unsigned(arg);
+    return true;
+}
+
 // Look for arguments (ta, idx) where ta is a TypedArray and idx is a
 // non-negative integer.
 // Check that accessBytes can be accessed starting from index idx in the array.
 // Return the array handle in typedArray and idx converted to a byte offset in byteStart.
 static bool
 TypedArrayFromArgs(JSContext* cx, const CallArgs& args, uint32_t accessBytes,
                    MutableHandleObject typedArray, size_t* byteStart)
 {
@@ -1345,21 +1353,20 @@ TypedArrayFromArgs(JSContext* cx, const 
 
     uint64_t index;
     if (!ArgumentToIntegerIndex(cx, args[1], &index))
         return false;
 
     // Do the range check in 64 bits even when size_t is 32 bits.
     // This can't overflow because index <= 2^53.
     uint64_t bytes = index * typedArray->as<TypedArrayObject>().bytesPerElement();
-    if ((bytes + accessBytes) > typedArray->as<TypedArrayObject>().byteLength()) {
-        // Keep in sync with AsmJS OnOutOfBounds function.
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_BAD_INDEX);
-        return false;
-    }
+    // Keep in sync with AsmJS OnOutOfBounds function.
+    if ((bytes + accessBytes) > typedArray->as<TypedArrayObject>().byteLength())
+        return ErrorBadIndex(cx);
+
     *byteStart = bytes;
 
     return true;
 }
 
 template<class V, unsigned NumElem>
 static bool
 Load(JSContext* cx, unsigned argc, Value* vp)
--- a/js/src/jit-test/tests/SIMD/replacelane.js
+++ b/js/src/jit-test/tests/SIMD/replacelane.js
@@ -56,29 +56,29 @@ function e() {
         assertEq(i < 149 || caught, true);
     }
 
     for (let i = 0; i < 150; i++) {
         let caught = false;
         try {
             let x = SIMD.Int32x4.replaceLane(i4, i < 149 ? 0 : 4, 42);
         } catch(e) {
-            assertEq(e instanceof TypeError, true);
+            assertEq(e instanceof RangeError, true);
             assertEq(i, 149);
             caught = true;
         }
         assertEq(i < 149 || caught, true);
     }
 
     for (let i = 0; i < 150; i++) {
         let caught = false;
         try {
             let x = SIMD.Int32x4.replaceLane(i4, i < 149 ? 0 : 1.1, 42);
         } catch(e) {
-            assertEq(e instanceof TypeError, true);
+            assertEq(e instanceof RangeError, true);
             assertEq(i, 149);
             caught = true;
         }
         assertEq(i < 149 || caught, true);
     }
 
     for (let i = 0; i < 150; i++) {
         let caught = false;
@@ -104,29 +104,29 @@ function e() {
         assertEq(i < 149 || caught, true);
     }
 
     for (let i = 0; i < 150; i++) {
         let caught = false;
         try {
             let x = SIMD.Float32x4.replaceLane(f4, i < 149 ? 0 : 4, 42);
         } catch(e) {
-            assertEq(e instanceof TypeError, true);
+            assertEq(e instanceof RangeError, true);
             assertEq(i, 149);
             caught = true;
         }
         assertEq(i < 149 || caught, true);
     }
 
     for (let i = 0; i < 150; i++) {
         let caught = false;
         try {
             let x = SIMD.Float32x4.replaceLane(f4, i < 149 ? 0 : 1.1, 42);
         } catch(e) {
-            assertEq(e instanceof TypeError, true);
+            assertEq(e instanceof RangeError, true);
             assertEq(i, 149);
             caught = true;
         }
         assertEq(i < 149 || caught, true);
     }
 
     for (let i = 0; i < 150; i++) {
         let caught = false;
@@ -152,29 +152,29 @@ function e() {
         assertEq(i < 149 || caught, true);
     }
 
     for (let i = 0; i < 150; i++) {
         let caught = false;
         try {
             let x = SIMD.Bool32x4.replaceLane(b4, i < 149 ? 0 : 4, true);
         } catch(e) {
-            assertEq(e instanceof TypeError, true);
+            assertEq(e instanceof RangeError, true);
             assertEq(i, 149);
             caught = true;
         }
         assertEq(i < 149 || caught, true);
     }
 
     for (let i = 0; i < 150; i++) {
         let caught = false;
         try {
             let x = SIMD.Bool32x4.replaceLane(b4, i < 149 ? 0 : 1.1, true);
         } catch(e) {
-            assertEq(e instanceof TypeError, true);
+            assertEq(e instanceof RangeError, true);
             assertEq(i, 149);
             caught = true;
         }
         assertEq(i < 149 || caught, true);
     }
 
 }
 
--- a/js/src/jit-test/tests/SIMD/shuffle.js
+++ b/js/src/jit-test/tests/SIMD/shuffle.js
@@ -48,37 +48,39 @@ function f() {
         var r = SIMD.Int32x4.shuffle(i1, i2, i % 8, (i + 1) % 8, (i + 2) % 8, (i + 3) % 8);
         assertEqX4(r, compI[i % 8]);
 
         // Constant lanes
         assertEqX4(SIMD.Int32x4.shuffle(i1, i2, 3, 2, 4, 5), [4, 3, 5, 6]);
     }
 }
 
-function testBailouts(uglyDuckling) {
+function testBailouts(expectException, uglyDuckling) {
     var i1 = SIMD.Int32x4(1, 2, 3, 4);
     var i2 = SIMD.Int32x4(5, 6, 7, 8);
 
     for (var i = 0; i < 150; i++) {
         // Test bailouts
-        var value = i == 149 ? uglyDuckling : 3;
+        var value = i == 149 ? uglyDuckling : 0;
         var caught = false;
         try {
-            assertEqX4(SIMD.Int32x4.shuffle(i1, i2, value, 2, 4, 5), [4, 3, 5, 6]);
+            assertEqX4(SIMD.Int32x4.shuffle(i1, i2, value, 2, 4, 5), [1, 3, 5, 6]);
         } catch(e) {
             print(e);
             caught = true;
             assertEq(i, 149);
-            assertEq(e instanceof TypeError, true);
+            assertEq(e instanceof TypeError || e instanceof RangeError, true);
         }
-        assertEq(i < 149 || caught, true);
+        if (i == 149)
+            assertEq(caught, expectException);
     }
 }
 
 f();
-testBailouts(-1);
-testBailouts(8);
-testBailouts(2.5);
-testBailouts(undefined);
-testBailouts(null);
-testBailouts({});
-testBailouts('one');
-testBailouts(true);
+testBailouts(true, -1);
+testBailouts(true, 8);
+testBailouts(true, 2.5);
+testBailouts(true, undefined);
+testBailouts(true, {});
+testBailouts(true, 'one');
+testBailouts(false, false);
+testBailouts(false, null);
+testBailouts(false, " 0.0 ");
--- a/js/src/jit-test/tests/SIMD/swizzle.js
+++ b/js/src/jit-test/tests/SIMD/swizzle.js
@@ -37,57 +37,59 @@ function f() {
         var r = SIMD.Int32x4.swizzle(i4, i % 4, (i + 1) % 4, (i + 2) % 4, (i + 3) % 4);
         assertEqX4(r, compI[i % 4]);
 
         // Constant lanes
         assertEqX4(SIMD.Int32x4.swizzle(i4, 3, 2, 1, 0), [4, 3, 2, 1]);
     }
 }
 
-function testBailouts(uglyDuckling) {
+function testBailouts(expectException, uglyDuckling) {
     var i4 = SIMD.Int32x4(1, 2, 3, 4);
     for (var i = 0; i < 150; i++) {
         // Test bailouts
         var value = i == 149 ? uglyDuckling : 0;
         var caught = false;
         try {
             assertEqX4(SIMD.Int32x4.swizzle(i4, value, 3, 2, 0), [1, 4, 3, 1]);
         } catch(e) {
             print(e);
             caught = true;
             assertEq(i, 149);
-            assertEq(e instanceof TypeError, true);
+            assertEq(e instanceof TypeError || e instanceof RangeError, true);
         }
-        assertEq(i < 149 || caught, true);
+        if (i == 149)
+            assertEq(caught, expectException);
     }
 }
 
 function testInt32x4SwizzleBailout() {
     // Test out-of-bounds non-constant indices. This is expected to throw.
     var i4 = SIMD.Int32x4(1, 2, 3, 4);
     for (var i = 0; i < 150; i++) {
         assertEqX4(SIMD.Int32x4.swizzle(i4, i, 3, 2, 0), [i + 1, 4, 3, 1]);
     }
 }
 
 f();
-testBailouts(-1);
-testBailouts(4);
-testBailouts(2.5);
-testBailouts(undefined);
-testBailouts(null);
-testBailouts({});
-testBailouts('one');
-testBailouts(true);
+testBailouts(true, -1);
+testBailouts(true, 4);
+testBailouts(true, 2.5);
+testBailouts(true, undefined);
+testBailouts(true, {});
+testBailouts(true, 'one');
+testBailouts(false, false);
+testBailouts(false, null);
+testBailouts(false, " 0.0 ");
 
 try {
     testInt32x4SwizzleBailout();
     throw 'not caught';
 } catch(e) {
-    assertEq(e instanceof TypeError, true);
+    assertEq(e instanceof RangeError, true);
 }
 
 (function() {
     var zappa = 0;
 
     function testBailouts() {
         var i4 = SIMD.Int32x4(1, 2, 3, 4);
         for (var i = 0; i < 300; i++) {
--- a/js/src/tests/ecma_7/SIMD/replaceLane.js
+++ b/js/src/tests/ecma_7/SIMD/replaceLane.js
@@ -83,144 +83,144 @@ function test() {
       [Float32x4(NaN, -0, Infinity, -Infinity), 0]
   ];
   testType('Float32x4', Float32x4inputs);
 
   var v = Float32x4inputs[1][0];
   assertEqX4(Float32x4.replaceLane(v, 0), replaceLane0(simdToArray(v), NaN));
   assertEqX4(Float32x4.replaceLane(v, 0, good), replaceLane0(simdToArray(v), good | 0));
   assertThrowsInstanceOf(() => Float32x4.replaceLane(v, 0, bad), TestError);
-  assertThrowsInstanceOf(() => Float32x4.replaceLane(v, 4, good), TypeError);
-  assertThrowsInstanceOf(() => Float32x4.replaceLane(v, 1.1, good), TypeError);
+  assertThrowsInstanceOf(() => Float32x4.replaceLane(v, 4, good), RangeError);
+  assertThrowsInstanceOf(() => Float32x4.replaceLane(v, 1.1, good), RangeError);
 
   var Float64x2inputs = [
       [Float64x2(1, 2), 5],
       [Float64x2(1.87, 2.08), Math.fround(13.37)],
       [Float64x2(NaN, -0), 0]
   ];
   testType('Float64x2', Float64x2inputs);
 
   var v = Float64x2inputs[1][0];
   assertEqX2(Float64x2.replaceLane(v, 0), replaceLane0(simdToArray(v), NaN));
   assertEqX2(Float64x2.replaceLane(v, 0, good), replaceLane0(simdToArray(v), good | 0));
   assertThrowsInstanceOf(() => Float64x2.replaceLane(v, 0, bad), TestError);
-  assertThrowsInstanceOf(() => Float64x2.replaceLane(v, 2, good), TypeError);
-  assertThrowsInstanceOf(() => Float64x2.replaceLane(v, 1.1, good), TypeError);
+  assertThrowsInstanceOf(() => Float64x2.replaceLane(v, 2, good), RangeError);
+  assertThrowsInstanceOf(() => Float64x2.replaceLane(v, 1.1, good), RangeError);
 
   var Int8x16inputs = [[Int8x16(0, 1, 2, 3, 4, 5, 6, 7, -1, -2, -3, -4, -5, -6, INT8_MIN, INT8_MAX), 17]];
   testType('Int8x16', Int8x16inputs);
 
   var v = Int8x16inputs[0][0];
   assertEqX16(Int8x16.replaceLane(v, 0), replaceLane0(simdToArray(v), 0));
   assertEqX16(Int8x16.replaceLane(v, 0, good), replaceLane0(simdToArray(v), good | 0));
   assertThrowsInstanceOf(() => Int8x16.replaceLane(v, 0, bad), TestError);
-  assertThrowsInstanceOf(() => Int8x16.replaceLane(v, 16, good), TypeError);
-  assertThrowsInstanceOf(() => Int8x16.replaceLane(v, 1.1, good), TypeError);
+  assertThrowsInstanceOf(() => Int8x16.replaceLane(v, 16, good), RangeError);
+  assertThrowsInstanceOf(() => Int8x16.replaceLane(v, 1.1, good), RangeError);
 
   var Int16x8inputs = [[Int16x8(0, 1, 2, 3, -1, -2, INT16_MIN, INT16_MAX), 9]];
   testType('Int16x8', Int16x8inputs);
 
   var v = Int16x8inputs[0][0];
   assertEqX8(Int16x8.replaceLane(v, 0), replaceLane0(simdToArray(v), 0));
   assertEqX8(Int16x8.replaceLane(v, 0, good), replaceLane0(simdToArray(v), good | 0));
   assertThrowsInstanceOf(() => Int16x8.replaceLane(v, 0, bad), TestError);
-  assertThrowsInstanceOf(() => Int16x8.replaceLane(v, 8, good), TypeError);
-  assertThrowsInstanceOf(() => Int16x8.replaceLane(v, 1.1, good), TypeError);
+  assertThrowsInstanceOf(() => Int16x8.replaceLane(v, 8, good), RangeError);
+  assertThrowsInstanceOf(() => Int16x8.replaceLane(v, 1.1, good), RangeError);
 
   var Int32x4inputs = [
       [Int32x4(1, 2, 3, 4), 5],
       [Int32x4(INT32_MIN, INT32_MAX, 3, 4), INT32_MIN],
   ];
   testType('Int32x4', Int32x4inputs);
 
   var v = Int32x4inputs[1][0];
   assertEqX4(Int32x4.replaceLane(v, 0), replaceLane0(simdToArray(v), 0));
   assertEqX4(Int32x4.replaceLane(v, 0, good), replaceLane0(simdToArray(v), good | 0));
   assertThrowsInstanceOf(() => Int32x4.replaceLane(v, 0, bad), TestError);
-  assertThrowsInstanceOf(() => Int32x4.replaceLane(v, 4, good), TypeError);
-  assertThrowsInstanceOf(() => Int32x4.replaceLane(v, 1.1, good), TypeError);
+  assertThrowsInstanceOf(() => Int32x4.replaceLane(v, 4, good), RangeError);
+  assertThrowsInstanceOf(() => Int32x4.replaceLane(v, 1.1, good), RangeError);
 
   var Uint8x16inputs = [[Uint8x16(0, 1, 2, 3, 4, 5, 6, 7, -1, -2, -3, -4, -5, -6, INT8_MIN, UINT8_MAX), 17]];
   testType('Uint8x16', Uint8x16inputs);
 
   var v = Uint8x16inputs[0][0];
   assertEqX16(Uint8x16.replaceLane(v, 0), replaceLane0(simdToArray(v), 0));
   assertEqX16(Uint8x16.replaceLane(v, 0, good), replaceLane0(simdToArray(v), good | 0));
   assertThrowsInstanceOf(() => Uint8x16.replaceLane(v, 0, bad), TestError);
-  assertThrowsInstanceOf(() => Uint8x16.replaceLane(v, 16, good), TypeError);
-  assertThrowsInstanceOf(() => Uint8x16.replaceLane(v, 1.1, good), TypeError);
+  assertThrowsInstanceOf(() => Uint8x16.replaceLane(v, 16, good), RangeError);
+  assertThrowsInstanceOf(() => Uint8x16.replaceLane(v, 1.1, good), RangeError);
 
   var Uint16x8inputs = [[Uint16x8(0, 1, 2, 3, -1, -2, INT16_MIN, UINT16_MAX), 9]];
   testType('Uint16x8', Uint16x8inputs);
 
   var v = Uint16x8inputs[0][0];
   assertEqX8(Uint16x8.replaceLane(v, 0), replaceLane0(simdToArray(v), 0));
   assertEqX8(Uint16x8.replaceLane(v, 0, good), replaceLane0(simdToArray(v), good | 0));
   assertThrowsInstanceOf(() => Uint16x8.replaceLane(v, 0, bad), TestError);
-  assertThrowsInstanceOf(() => Uint16x8.replaceLane(v, 8, good), TypeError);
-  assertThrowsInstanceOf(() => Uint16x8.replaceLane(v, 1.1, good), TypeError);
+  assertThrowsInstanceOf(() => Uint16x8.replaceLane(v, 8, good), RangeError);
+  assertThrowsInstanceOf(() => Uint16x8.replaceLane(v, 1.1, good), RangeError);
 
   var Uint32x4inputs = [
       [Uint32x4(1, 2, 3, 4), 5],
       [Uint32x4(INT32_MIN, UINT32_MAX, INT32_MAX, 4), UINT32_MAX],
   ];
   testType('Uint32x4', Uint32x4inputs);
 
   var v = Uint32x4inputs[1][0];
   assertEqX4(Uint32x4.replaceLane(v, 0), replaceLane0(simdToArray(v), 0));
   assertEqX4(Uint32x4.replaceLane(v, 0, good), replaceLane0(simdToArray(v), good | 0));
   assertThrowsInstanceOf(() => Uint32x4.replaceLane(v, 0, bad), TestError);
-  assertThrowsInstanceOf(() => Uint32x4.replaceLane(v, 4, good), TypeError);
-  assertThrowsInstanceOf(() => Uint32x4.replaceLane(v, 1.1, good), TypeError);
+  assertThrowsInstanceOf(() => Uint32x4.replaceLane(v, 4, good), RangeError);
+  assertThrowsInstanceOf(() => Uint32x4.replaceLane(v, 1.1, good), RangeError);
 
   var Bool64x2inputs = [
       [Bool64x2(true, true), false],
   ];
   testType('Bool64x2', Bool64x2inputs);
 
   var v = Bool64x2inputs[0][0];
   assertEqX2(Bool64x2.replaceLane(v, 0),       replaceLane0(simdToArray(v), false));
   assertEqX2(Bool64x2.replaceLane(v, 0, true), replaceLane0(simdToArray(v), true));
   assertEqX2(Bool64x2.replaceLane(v, 0, bad),  replaceLane0(simdToArray(v), true));
-  assertThrowsInstanceOf(() => Bool64x2.replaceLane(v, 4, true), TypeError);
-  assertThrowsInstanceOf(() => Bool64x2.replaceLane(v, 1.1, false), TypeError);
+  assertThrowsInstanceOf(() => Bool64x2.replaceLane(v, 4, true), RangeError);
+  assertThrowsInstanceOf(() => Bool64x2.replaceLane(v, 1.1, false), RangeError);
 
   var Bool32x4inputs = [
       [Bool32x4(true, true, true, true), false],
   ];
   testType('Bool32x4', Bool32x4inputs);
 
   var v = Bool32x4inputs[0][0];
   assertEqX4(Bool32x4.replaceLane(v, 0),       replaceLane0(simdToArray(v), false));
   assertEqX4(Bool32x4.replaceLane(v, 0, true), replaceLane0(simdToArray(v), true));
   assertEqX4(Bool32x4.replaceLane(v, 0, bad),  replaceLane0(simdToArray(v), true));
-  assertThrowsInstanceOf(() => Bool32x4.replaceLane(v, 4, true), TypeError);
-  assertThrowsInstanceOf(() => Bool32x4.replaceLane(v, 1.1, false), TypeError);
+  assertThrowsInstanceOf(() => Bool32x4.replaceLane(v, 4, true), RangeError);
+  assertThrowsInstanceOf(() => Bool32x4.replaceLane(v, 1.1, false), RangeError);
 
   var Bool16x8inputs = [
       [Bool16x8(true, true, true, true, true, true, true, true), false],
   ];
 
   testType('Bool16x8', Bool16x8inputs);
   var v = Bool16x8inputs[0][0];
   assertEqX8(Bool16x8.replaceLane(v, 0),       replaceLane0(simdToArray(v), false));
   assertEqX8(Bool16x8.replaceLane(v, 0, true), replaceLane0(simdToArray(v), true));
   assertEqX8(Bool16x8.replaceLane(v, 0, bad),  replaceLane0(simdToArray(v), true));
-  assertThrowsInstanceOf(() => Bool16x8.replaceLane(v, 16, true), TypeError);
-  assertThrowsInstanceOf(() => Bool16x8.replaceLane(v, 1.1, false), TypeError);
+  assertThrowsInstanceOf(() => Bool16x8.replaceLane(v, 16, true), RangeError);
+  assertThrowsInstanceOf(() => Bool16x8.replaceLane(v, 1.1, false), RangeError);
 
   var Bool8x16inputs = [
       [Bool8x16(true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true), false],
   ];
 
   testType('Bool8x16', Bool8x16inputs);
   var v = Bool8x16inputs[0][0];
   assertEqX16(Bool8x16.replaceLane(v, 0),       replaceLane0(simdToArray(v), false));
   assertEqX16(Bool8x16.replaceLane(v, 0, true), replaceLane0(simdToArray(v), true));
   assertEqX16(Bool8x16.replaceLane(v, 0, bad),  replaceLane0(simdToArray(v), true));
-  assertThrowsInstanceOf(() => Bool8x16.replaceLane(v, 16, true), TypeError);
-  assertThrowsInstanceOf(() => Bool8x16.replaceLane(v, 1.1, false), TypeError);
+  assertThrowsInstanceOf(() => Bool8x16.replaceLane(v, 16, true), RangeError);
+  assertThrowsInstanceOf(() => Bool8x16.replaceLane(v, 1.1, false), RangeError);
 
   if (typeof reportCompare === "function")
     reportCompare(true, true);
 }
 
 test();
--- a/js/src/tests/ecma_7/SIMD/swizzle-shuffle.js
+++ b/js/src/tests/ecma_7/SIMD/swizzle-shuffle.js
@@ -100,67 +100,79 @@ function testSwizzleForType(type) {
                     [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
                     [15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0],
                     [5, 14, 3, 2, 6, 9, 1, 10, 7, 11, 4, 0, 13, 15, 8, 12]];
         for (var t of vals) {
           assertEqVec(type.swizzle(v, ...t), swizzle16(simdToArray(v), ...t));
         }
     }
 
-    // Test that we throw if an lane argument isn't an int32 or isn't in bounds.
+    // Test that we throw if an lane argument doesn't coerce to an integer in bounds.
     if (lanes == 2) {
-        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0.5), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(v, 0, {}), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(v, 0, {valueOf: function(){return 42}}), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(v, 0, "one"), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(v, 0, null), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(v, 0, undefined), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(v, 0, true), TypeError);
+        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0.5), RangeError);
+        assertThrowsInstanceOf(() => type.swizzle(v, 0, {}), RangeError);
+        assertThrowsInstanceOf(() => type.swizzle(v, 0, {valueOf: function(){return 42}}), RangeError);
+        assertThrowsInstanceOf(() => type.swizzle(v, 0, "one"), RangeError);
+        assertThrowsInstanceOf(() => type.swizzle(v, 0, undefined), RangeError);
+
+        type.swizzle(v, 0, "00.0");
+        type.swizzle(v, 0, null);
+        type.swizzle(v, 0, false);
+        type.swizzle(v, 0, true);
 
         // In bounds is [0, 1]
-        assertThrowsInstanceOf(() => type.swizzle(v, 0, -1), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(v, 0, 2), TypeError);
+        assertThrowsInstanceOf(() => type.swizzle(v, 0, -1), RangeError);
+        assertThrowsInstanceOf(() => type.swizzle(v, 0, 2), RangeError);
     } else if (lanes == 4) {
-        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0.5), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, {}), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, {valueOf: function(){return 42}}), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, "one"), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, null), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, undefined), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, true), TypeError);
+        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0.5), RangeError);
+        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, {}), RangeError);
+        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, {valueOf: function(){return 42}}), RangeError);
+        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, "one"), RangeError);
+        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, undefined), RangeError);
+
+        type.swizzle(v, 0, 0, 0, "00.0");
+        type.swizzle(v, 0, 0, 0, null);
+        type.swizzle(v, 0, 0, 0, false);
+        type.swizzle(v, 0, 0, 0, true);
 
         // In bounds is [0, 3]
-        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, -1), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 4), TypeError);
+        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, -1), RangeError);
+        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 4), RangeError);
     } else if (lanes == 8) {
-        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0.5), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, {}), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, {valueOf: function(){return 42}}), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, "one"), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, null), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, undefined), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, true), TypeError);
+        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0.5), RangeError);
+        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, {}), RangeError);
+        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, {valueOf: function(){return 42}}), RangeError);
+        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, "one"), RangeError);
+        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, undefined), RangeError);
+
+        type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, "00.0");
+        type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, null);
+        type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, false);
+        type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, true);
 
         // In bounds is [0, 7]
-        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, -1), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 8), TypeError);
+        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, -1), RangeError);
+        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 8), RangeError);
     } else {
         assertEq(lanes, 16);
 
-        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.5), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {valueOf: function(){return 42}}), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "one"), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, null), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, undefined), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, true), TypeError);
+        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.5), RangeError);
+        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}), RangeError);
+        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {valueOf: function(){return 42}}), RangeError);
+        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "one"), RangeError);
+        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, undefined), RangeError);
+
+        type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "00.0");
+        type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, null);
+        type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, false);
+        type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, true);
 
         // In bounds is [0, 15]
-        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16), TypeError);
+        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1), RangeError);
+        assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16), RangeError);
     }
 }
 
 function testSwizzleInt8x16() {
     var v = Int16x8(1, 2, 3, 4, 5, 6, 7, 8);
 
     assertThrowsInstanceOf(function() {
         Int8x16.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
@@ -345,65 +357,57 @@ function testShuffleForType(type) {
             [s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15] = t;
             assertEqVec(type.shuffle(lhs, rhs, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15),
                         shuffle16(simdToArray(lhs), simdToArray(rhs), s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15));
         }
     }
 
     // Test that we throw if an lane argument isn't an int32 or isn't in bounds.
     if (lanes == 2) {
-        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0.5), TypeError);
-        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, {}), TypeError);
-        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, {valueOf: function(){return 42}}), TypeError);
-        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, "one"), TypeError);
-        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, null), TypeError);
-        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, undefined), TypeError);
-        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, true), TypeError);
+        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0.5), RangeError);
+        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, {}), RangeError);
+        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, {valueOf: function(){return 42}}), RangeError);
+        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, "one"), RangeError);
+        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, undefined), RangeError);
 
         // In bounds is [0, 3]
-        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, -1), TypeError);
-        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 4), TypeError);
+        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, -1), RangeError);
+        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 4), RangeError);
     } else if (lanes == 4) {
-        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, 0.5), TypeError);
-        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, {}), TypeError);
-        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, {valueOf: function(){return 42}}), TypeError);
-        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, "one"), TypeError);
-        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, null), TypeError);
-        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, undefined), TypeError);
-        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, true), TypeError);
+        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, 0.5), RangeError);
+        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, {}), RangeError);
+        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, {valueOf: function(){return 42}}), RangeError);
+        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, "one"), RangeError);
+        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, undefined), RangeError);
 
         // In bounds is [0, 7]
-        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, -1), TypeError);
-        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, 8), TypeError);
+        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, -1), RangeError);
+        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, 8), RangeError);
     } else if (lanes == 8) {
-        assertThrowsInstanceOf(() => type.swizzle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 0.5), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, {}), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, {valueOf: function(){return 42}}), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, "one"), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, null), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, undefined), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, true), TypeError);
+        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 0.5), RangeError);
+        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, {}), RangeError);
+        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, {valueOf: function(){return 42}}), RangeError);
+        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, "one"), RangeError);
+        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, undefined), RangeError);
 
         // In bounds is [0, 15]
-        assertThrowsInstanceOf(() => type.swizzle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, -1), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 16), TypeError);
+        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, -1), RangeError);
+        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 16), RangeError);
     } else {
         assertEq(lanes, 16);
 
-        assertThrowsInstanceOf(() => type.swizzle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.5), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {valueOf: function(){return 42}}), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "one"), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, null), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, undefined), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, true), TypeError);
+        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.5), RangeError);
+        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}), RangeError);
+        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {valueOf: function(){return 42}}), RangeError);
+        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "one"), RangeError);
+        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, undefined), RangeError);
 
         // In bounds is [0, 31]
-        assertThrowsInstanceOf(() => type.swizzle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1), TypeError);
-        assertThrowsInstanceOf(() => type.swizzle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32), TypeError);
+        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1), RangeError);
+        assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32), RangeError);
     }
 }
 
 function testShuffleInt8x16() {
     var v = Int16x8(1, 2, 3, 4, 5, 6, 7, 8);
 
     assertThrowsInstanceOf(function() {
         Int8x16.shuffle(v, v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
--- a/js/src/tests/ecma_7/SIMD/typedobjects.js
+++ b/js/src/tests/ecma_7/SIMD/typedobjects.js
@@ -27,20 +27,20 @@ function testFloat32x4Alignment() {
 
 function testFloat32x4Getters() {
   var f = Float32x4(11, 22, 33, 44);
   assertEq(Float32x4.extractLane(f, 0), 11);
   assertEq(Float32x4.extractLane(f, 1), 22);
   assertEq(Float32x4.extractLane(f, 2), 33);
   assertEq(Float32x4.extractLane(f, 3), 44);
 
-  assertThrowsInstanceOf(() => Float32x4.extractLane(f, 4), TypeError);
-  assertThrowsInstanceOf(() => Float32x4.extractLane(f, -1), TypeError);
-  assertThrowsInstanceOf(() => Float32x4.extractLane(f, 0.5), TypeError);
-  assertThrowsInstanceOf(() => Float32x4.extractLane(f, {}), TypeError);
+  assertThrowsInstanceOf(() => Float32x4.extractLane(f, 4), RangeError);
+  assertThrowsInstanceOf(() => Float32x4.extractLane(f, -1), RangeError);
+  assertThrowsInstanceOf(() => Float32x4.extractLane(f, 0.5), RangeError);
+  assertThrowsInstanceOf(() => Float32x4.extractLane(f, {}), RangeError);
   assertThrowsInstanceOf(() => Float32x4.extractLane(Int32x4(1,2,3,4), 0), TypeError);
   assertThrowsInstanceOf(() => Float32x4.extractLane(1, 0), TypeError);
   assertThrowsInstanceOf(() => Float32x4.extractLane(f, f), TypeError);
 }
 
 function testFloat32x4Handles() {
   var Array = Float32x4.array(3);
   var array = new Array([Float32x4(1, 2, 3, 4),
@@ -113,20 +113,20 @@ function testFloat64x2Alignment() {
 }
 
 function testFloat64x2Getters() {
   // Create a Float64x2 and check that the getters work:
   var f = Float64x2(11, 22);
   assertEq(Float64x2.extractLane(f, 0), 11);
   assertEq(Float64x2.extractLane(f, 1), 22);
 
-  assertThrowsInstanceOf(() => Float64x2.extractLane(f, 2), TypeError);
-  assertThrowsInstanceOf(() => Float64x2.extractLane(f, -1), TypeError);
-  assertThrowsInstanceOf(() => Float64x2.extractLane(f, 0.5), TypeError);
-  assertThrowsInstanceOf(() => Float64x2.extractLane(f, {}), TypeError);
+  assertThrowsInstanceOf(() => Float64x2.extractLane(f, 2), RangeError);
+  assertThrowsInstanceOf(() => Float64x2.extractLane(f, -1), RangeError);
+  assertThrowsInstanceOf(() => Float64x2.extractLane(f, 0.5), RangeError);
+  assertThrowsInstanceOf(() => Float64x2.extractLane(f, {}), RangeError);
   assertThrowsInstanceOf(() => Float64x2.extractLane(Float32x4(1,2,3,4), 0), TypeError);
   assertThrowsInstanceOf(() => Float64x2.extractLane(1, 0), TypeError);
   assertThrowsInstanceOf(() => Float64x2.extractLane(f, f), TypeError);
 }
 
 function testFloat64x2Handles() {
   var Array = Float64x2.array(3);
   var array = new Array([Float64x2(1, 2),
@@ -213,20 +213,20 @@ function testInt8x16Getters() {
   assertEq(Int8x16.extractLane(f, 9), 10);
   assertEq(Int8x16.extractLane(f, 10), 20);
   assertEq(Int8x16.extractLane(f, 11), 30);
   assertEq(Int8x16.extractLane(f, 12), 40);
   assertEq(Int8x16.extractLane(f, 13), 50);
   assertEq(Int8x16.extractLane(f, 14), 60);
   assertEq(Int8x16.extractLane(f, 15), 70);
 
-  assertThrowsInstanceOf(() => Int8x16.extractLane(f, 16), TypeError);
-  assertThrowsInstanceOf(() => Int8x16.extractLane(f, -1), TypeError);
-  assertThrowsInstanceOf(() => Int8x16.extractLane(f, 0.5), TypeError);
-  assertThrowsInstanceOf(() => Int8x16.extractLane(f, {}), TypeError);
+  assertThrowsInstanceOf(() => Int8x16.extractLane(f, 16), RangeError);
+  assertThrowsInstanceOf(() => Int8x16.extractLane(f, -1), RangeError);
+  assertThrowsInstanceOf(() => Int8x16.extractLane(f, 0.5), RangeError);
+  assertThrowsInstanceOf(() => Int8x16.extractLane(f, {}), RangeError);
   assertThrowsInstanceOf(() => Int8x16.extractLane(Int32x4(1,2,3,4), 0), TypeError);
   assertThrowsInstanceOf(() => Int8x16.extractLane(1, 0), TypeError);
   assertThrowsInstanceOf(() => Int8x16.extractLane(f, f), TypeError);
 }
 
 function testInt8x16Handles() {
   var Array = Int8x16.array(3);
   var array = new Array([Int8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16),
@@ -309,20 +309,20 @@ function testInt16x8Getters() {
   assertEq(Int16x8.extractLane(f, 1), 22);
   assertEq(Int16x8.extractLane(f, 2), 33);
   assertEq(Int16x8.extractLane(f, 3), 44);
   assertEq(Int16x8.extractLane(f, 4), 55);
   assertEq(Int16x8.extractLane(f, 5), 66);
   assertEq(Int16x8.extractLane(f, 6), 77);
   assertEq(Int16x8.extractLane(f, 7), 88);
 
-  assertThrowsInstanceOf(() => Int16x8.extractLane(f, 8), TypeError);
-  assertThrowsInstanceOf(() => Int16x8.extractLane(f, -1), TypeError);
-  assertThrowsInstanceOf(() => Int16x8.extractLane(f, 0.5), TypeError);
-  assertThrowsInstanceOf(() => Int16x8.extractLane(f, {}), TypeError);
+  assertThrowsInstanceOf(() => Int16x8.extractLane(f, 8), RangeError);
+  assertThrowsInstanceOf(() => Int16x8.extractLane(f, -1), RangeError);
+  assertThrowsInstanceOf(() => Int16x8.extractLane(f, 0.5), RangeError);
+  assertThrowsInstanceOf(() => Int16x8.extractLane(f, {}), RangeError);
   assertThrowsInstanceOf(() => Int16x8.extractLane(Int32x4(1,2,3,4), 0), TypeError);
   assertThrowsInstanceOf(() => Int16x8.extractLane(1, 0), TypeError);
   assertThrowsInstanceOf(() => Int16x8.extractLane(f, f), TypeError);
 }
 
 function testInt16x8Handles() {
   var Array = Int16x8.array(3);
   var array = new Array([Int16x8(1, 2, 3, 4, 5, 6, 7, 8),
@@ -397,20 +397,20 @@ function testInt32x4Alignment() {
 function testInt32x4Getters() {
   // Create a Int32x4 and check that the getters work:
   var f = Int32x4(11, 22, 33, 44);
   assertEq(Int32x4.extractLane(f, 0), 11);
   assertEq(Int32x4.extractLane(f, 1), 22);
   assertEq(Int32x4.extractLane(f, 2), 33);
   assertEq(Int32x4.extractLane(f, 3), 44);
 
-  assertThrowsInstanceOf(() => Int32x4.extractLane(f, 4), TypeError);
-  assertThrowsInstanceOf(() => Int32x4.extractLane(f, -1), TypeError);
-  assertThrowsInstanceOf(() => Int32x4.extractLane(f, 0.5), TypeError);
-  assertThrowsInstanceOf(() => Int32x4.extractLane(f, {}), TypeError);
+  assertThrowsInstanceOf(() => Int32x4.extractLane(f, 4), RangeError);
+  assertThrowsInstanceOf(() => Int32x4.extractLane(f, -1), RangeError);
+  assertThrowsInstanceOf(() => Int32x4.extractLane(f, 0.5), RangeError);
+  assertThrowsInstanceOf(() => Int32x4.extractLane(f, {}), RangeError);
   assertThrowsInstanceOf(() => Int32x4.extractLane(Float32x4(1,2,3,4), 0), TypeError);
   assertThrowsInstanceOf(() => Int32x4.extractLane(1, 0), TypeError);
   assertThrowsInstanceOf(() => Int32x4.extractLane(f, f), TypeError);
 }
 
 function testInt32x4Handles() {
   var Array = Int32x4.array(3);
   var array = new Array([Int32x4(1, 2, 3, 4),
@@ -496,20 +496,20 @@ function testUint8x16Getters() {
   assertEq(Uint8x16.extractLane(f, 9), 10);
   assertEq(Uint8x16.extractLane(f, 10), 20);
   assertEq(Uint8x16.extractLane(f, 11), 30);
   assertEq(Uint8x16.extractLane(f, 12), 40);
   assertEq(Uint8x16.extractLane(f, 13), 50);
   assertEq(Uint8x16.extractLane(f, 14), 60);
   assertEq(Uint8x16.extractLane(f, 15), 70);
 
-  assertThrowsInstanceOf(() => Uint8x16.extractLane(f, 16), TypeError);
-  assertThrowsInstanceOf(() => Uint8x16.extractLane(f, -1), TypeError);
-  assertThrowsInstanceOf(() => Uint8x16.extractLane(f, 0.5), TypeError);
-  assertThrowsInstanceOf(() => Uint8x16.extractLane(f, {}), TypeError);
+  assertThrowsInstanceOf(() => Uint8x16.extractLane(f, 16), RangeError);
+  assertThrowsInstanceOf(() => Uint8x16.extractLane(f, -1), RangeError);
+  assertThrowsInstanceOf(() => Uint8x16.extractLane(f, 0.5), RangeError);
+  assertThrowsInstanceOf(() => Uint8x16.extractLane(f, {}), RangeError);
   assertThrowsInstanceOf(() => Uint8x16.extractLane(Uint32x4(1,2,3,4), 0), TypeError);
   assertThrowsInstanceOf(() => Uint8x16.extractLane(1, 0), TypeError);
   assertThrowsInstanceOf(() => Uint8x16.extractLane(f, f), TypeError);
 }
 
 function testUint8x16Handles() {
   var Array = Uint8x16.array(3);
   var array = new Array([Uint8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16),
@@ -592,20 +592,20 @@ function testUint16x8Getters() {
   assertEq(Uint16x8.extractLane(f, 1), 22);
   assertEq(Uint16x8.extractLane(f, 2), 33);
   assertEq(Uint16x8.extractLane(f, 3), 44);
   assertEq(Uint16x8.extractLane(f, 4), 55);
   assertEq(Uint16x8.extractLane(f, 5), 66);
   assertEq(Uint16x8.extractLane(f, 6), 77);
   assertEq(Uint16x8.extractLane(f, 7), 88);
 
-  assertThrowsInstanceOf(() => Uint16x8.extractLane(f, 8), TypeError);
-  assertThrowsInstanceOf(() => Uint16x8.extractLane(f, -1), TypeError);
-  assertThrowsInstanceOf(() => Uint16x8.extractLane(f, 0.5), TypeError);
-  assertThrowsInstanceOf(() => Uint16x8.extractLane(f, {}), TypeError);
+  assertThrowsInstanceOf(() => Uint16x8.extractLane(f, 8), RangeError);
+  assertThrowsInstanceOf(() => Uint16x8.extractLane(f, -1), RangeError);
+  assertThrowsInstanceOf(() => Uint16x8.extractLane(f, 0.5), RangeError);
+  assertThrowsInstanceOf(() => Uint16x8.extractLane(f, {}), RangeError);
   assertThrowsInstanceOf(() => Uint16x8.extractLane(Uint32x4(1,2,3,4), 0), TypeError);
   assertThrowsInstanceOf(() => Uint16x8.extractLane(1, 0), TypeError);
   assertThrowsInstanceOf(() => Uint16x8.extractLane(f, f), TypeError);
 }
 
 function testUint16x8Handles() {
   var Array = Uint16x8.array(3);
   var array = new Array([Uint16x8(1, 2, 3, 4, 5, 6, 7, 8),
@@ -680,20 +680,20 @@ function testUint32x4Alignment() {
 function testUint32x4Getters() {
   // Create a Uint32x4 and check that the getters work:
   var f = Uint32x4(11, 22, 33, 44);
   assertEq(Uint32x4.extractLane(f, 0), 11);
   assertEq(Uint32x4.extractLane(f, 1), 22);
   assertEq(Uint32x4.extractLane(f, 2), 33);
   assertEq(Uint32x4.extractLane(f, 3), 44);
 
-  assertThrowsInstanceOf(() => Uint32x4.extractLane(f, 4), TypeError);
-  assertThrowsInstanceOf(() => Uint32x4.extractLane(f, -1), TypeError);
-  assertThrowsInstanceOf(() => Uint32x4.extractLane(f, 0.5), TypeError);
-  assertThrowsInstanceOf(() => Uint32x4.extractLane(f, {}), TypeError);
+  assertThrowsInstanceOf(() => Uint32x4.extractLane(f, 4), RangeError);
+  assertThrowsInstanceOf(() => Uint32x4.extractLane(f, -1), RangeError);
+  assertThrowsInstanceOf(() => Uint32x4.extractLane(f, 0.5), RangeError);
+  assertThrowsInstanceOf(() => Uint32x4.extractLane(f, {}), RangeError);
   assertThrowsInstanceOf(() => Uint32x4.extractLane(Float32x4(1,2,3,4), 0), TypeError);
   assertThrowsInstanceOf(() => Uint32x4.extractLane(1, 0), TypeError);
   assertThrowsInstanceOf(() => Uint32x4.extractLane(f, f), TypeError);
 }
 
 function testUint32x4Handles() {
   var Array = Uint32x4.array(3);
   var array = new Array([Uint32x4(1, 2, 3, 4),
@@ -769,20 +769,20 @@ function testBool8x16Getters() {
   assertEq(Bool8x16.extractLane(f, 9), true);
   assertEq(Bool8x16.extractLane(f, 10), false);
   assertEq(Bool8x16.extractLane(f, 11), false);
   assertEq(Bool8x16.extractLane(f, 12), true);
   assertEq(Bool8x16.extractLane(f, 13), true);
   assertEq(Bool8x16.extractLane(f, 14), false);
   assertEq(Bool8x16.extractLane(f, 15), false);
 
-  assertThrowsInstanceOf(() => Bool8x16.extractLane(f, 16), TypeError);
-  assertThrowsInstanceOf(() => Bool8x16.extractLane(f, -1), TypeError);
-  assertThrowsInstanceOf(() => Bool8x16.extractLane(f, 0.5), TypeError);
-  assertThrowsInstanceOf(() => Bool8x16.extractLane(f, {}), TypeError);
+  assertThrowsInstanceOf(() => Bool8x16.extractLane(f, 16), RangeError);
+  assertThrowsInstanceOf(() => Bool8x16.extractLane(f, -1), RangeError);
+  assertThrowsInstanceOf(() => Bool8x16.extractLane(f, 0.5), RangeError);
+  assertThrowsInstanceOf(() => Bool8x16.extractLane(f, {}), RangeError);
   assertThrowsInstanceOf(() => Bool8x16.extractLane(Float32x4(1, 2, 3, 4), 0), TypeError);
   assertThrowsInstanceOf(() => Bool8x16.extractLane(1, 0), TypeError);
   assertThrowsInstanceOf(() => Bool8x16.extractLane(f, f), TypeError);
 }
 
 function testBool8x16Reify() {
   var Array = Bool8x16.array(3);
   var array = new Array([Bool8x16(true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false),
@@ -832,20 +832,20 @@ function testBool16x8Getters() {
   assertEq(Bool16x8.extractLane(f, 1), false);
   assertEq(Bool16x8.extractLane(f, 2), true);
   assertEq(Bool16x8.extractLane(f, 3), false);
   assertEq(Bool16x8.extractLane(f, 4), true);
   assertEq(Bool16x8.extractLane(f, 5), true);
   assertEq(Bool16x8.extractLane(f, 6), false);
   assertEq(Bool16x8.extractLane(f, 7), false);
 
-  assertThrowsInstanceOf(() => Bool16x8.extractLane(f, 8), TypeError);
-  assertThrowsInstanceOf(() => Bool16x8.extractLane(f, -1), TypeError);
-  assertThrowsInstanceOf(() => Bool16x8.extractLane(f, 0.5), TypeError);
-  assertThrowsInstanceOf(() => Bool16x8.extractLane(f, {}), TypeError);
+  assertThrowsInstanceOf(() => Bool16x8.extractLane(f, 8), RangeError);
+  assertThrowsInstanceOf(() => Bool16x8.extractLane(f, -1), RangeError);
+  assertThrowsInstanceOf(() => Bool16x8.extractLane(f, 0.5), RangeError);
+  assertThrowsInstanceOf(() => Bool16x8.extractLane(f, {}), RangeError);
   assertThrowsInstanceOf(() => Bool16x8.extractLane(Float32x4(1, 2, 3, 4), 0), TypeError);
   assertThrowsInstanceOf(() => Bool16x8.extractLane(1, 0), TypeError);
   assertThrowsInstanceOf(() => Bool16x8.extractLane(f, f), TypeError);
 }
 
 function testBool16x8Reify() {
   var Array = Bool16x8.array(3);
   var array = new Array([Bool16x8(true, false, true, false, true, false, true, false),
@@ -888,20 +888,20 @@ function testBool16x8Setters() {
 
 function testBool32x4Getters() {
   // Create a Bool32x4 and check that the getters work:
   var f = Bool32x4(true, false, false, true);
   assertEq(Bool32x4.extractLane(f, 0), true);
   assertEq(Bool32x4.extractLane(f, 1), false);
   assertEq(Bool32x4.extractLane(f, 2), false);
   assertEq(Bool32x4.extractLane(f, 3), true);
-  assertThrowsInstanceOf(() => Bool32x4.extractLane(f, 4), TypeError);
-  assertThrowsInstanceOf(() => Bool32x4.extractLane(f, -1), TypeError);
-  assertThrowsInstanceOf(() => Bool32x4.extractLane(f, 0.5), TypeError);
-  assertThrowsInstanceOf(() => Bool32x4.extractLane(f, {}), TypeError);
+  assertThrowsInstanceOf(() => Bool32x4.extractLane(f, 4), RangeError);
+  assertThrowsInstanceOf(() => Bool32x4.extractLane(f, -1), RangeError);
+  assertThrowsInstanceOf(() => Bool32x4.extractLane(f, 0.5), RangeError);
+  assertThrowsInstanceOf(() => Bool32x4.extractLane(f, {}), RangeError);
   assertThrowsInstanceOf(() => Bool32x4.extractLane(Float32x4(1, 2, 3, 4), 0), TypeError);
   assertThrowsInstanceOf(() => Bool32x4.extractLane(1, 0), TypeError);
   assertThrowsInstanceOf(() => Bool32x4.extractLane(f, f), TypeError);
 }
 
 function testBool32x4Reify() {
   var Array = Bool32x4.array(3);
   var array = new Array([Bool32x4(true, false, false, true),
@@ -945,20 +945,20 @@ function testBool32x4Setters() {
 }
 
 function testBool64x2Getters() {
   // Create a Bool64x2 and check that the getters work:
   var f = Bool64x2(true, false);
   assertEq(Bool64x2.extractLane(f, 0), true);
   assertEq(Bool64x2.extractLane(f, 1), false);
 
-  assertThrowsInstanceOf(() => Bool64x2.extractLane(f, 2), TypeError);
-  assertThrowsInstanceOf(() => Bool64x2.extractLane(f, -1), TypeError);
-  assertThrowsInstanceOf(() => Bool64x2.extractLane(f, 0.5), TypeError);
-  assertThrowsInstanceOf(() => Bool64x2.extractLane(f, {}), TypeError);
+  assertThrowsInstanceOf(() => Bool64x2.extractLane(f, 2), RangeError);
+  assertThrowsInstanceOf(() => Bool64x2.extractLane(f, -1), RangeError);
+  assertThrowsInstanceOf(() => Bool64x2.extractLane(f, 0.5), RangeError);
+  assertThrowsInstanceOf(() => Bool64x2.extractLane(f, {}), RangeError);
   assertThrowsInstanceOf(() => Bool64x2.extractLane(Bool32x4(1,2,3,4), 0), TypeError);
   assertThrowsInstanceOf(() => Bool64x2.extractLane(1, 0), TypeError);
   assertThrowsInstanceOf(() => Bool64x2.extractLane(f, f), TypeError);
 }
 
 function testBool64x2Reify() {
   var Array = Bool64x2.array(3);
   var array = new Array([Bool64x2(true, false),