Back out bug 1256376 for now until I can figure out what's going on with it. I am sorry for the CLOSED TREE.
authorBoris Zbarsky <bzbarsky@mit.edu>
Tue, 22 Mar 2016 19:27:47 -0400
changeset 327804 102696dd72b5113694d8e432178ac9c7a9a0cabd
parent 327803 fd8964d81f842e0bca4c7c3024cb798242119491
child 327805 0d679fcadda5c6a0940124d5be75d99826dacb72
push id6048
push userkmoir@mozilla.com
push dateMon, 06 Jun 2016 19:02:08 +0000
treeherdermozilla-beta@46d72a56c57d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1256376
milestone48.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
Back out bug 1256376 for now until I can figure out what's going on with it. I am sorry for the CLOSED TREE.
js/src/builtin/TypedArray.js
js/src/vm/SelfHosting.cpp
js/xpconnect/tests/chrome/test_xrayToJS.xul
--- a/js/src/builtin/TypedArray.js
+++ b/js/src/builtin/TypedArray.js
@@ -37,35 +37,16 @@ function IsDetachedBuffer(buffer) {
 
 function GetAttachedArrayBuffer(tarray) {
     var buffer = ViewedArrayBufferIfReified(tarray);
     if (IsDetachedBuffer(buffer))
         ThrowTypeError(JSMSG_TYPED_ARRAY_DETACHED);
     return buffer;
 }
 
-// A function which ensures that the argument is either a typed array or a
-// cross-compartment wrapper for a typed array and that the typed array involved
-// has an attached array buffer.  If one of those conditions doesn't hold (wrong
-// kind of argument, or detached array buffer), an exception is thrown.  The
-// return value is `true` if the argument is a typed array, `false` if it's a
-// cross-compartment wrapper for a typed array.
-function IsTypedArrayEnsuringArrayBuffer(arg) {
-    if (IsObject(arg) && IsTypedArray(arg)) {
-        GetAttachedArrayBuffer(arg);
-        return true;
-    }
-
-    // This is a bit hacky but gets the job done: the first `arg` is used to
-    // test for a wrapped typed array, the second as an argument to
-    // GetAttachedArrayBuffer.
-    callFunction(CallTypedArrayMethodIfWrapped, arg, arg, "GetAttachedArrayBuffer");
-    return false;
-}
-
 // ES6 draft 20150304 %TypedArray%.prototype.copyWithin
 function TypedArrayCopyWithin(target, start, end = undefined) {
     // This function is not generic.
     if (!IsObject(this) || !IsTypedArray(this)) {
         return callFunction(CallTypedArrayMethodIfWrapped, this, target, start, end,
                             "TypedArrayCopyWithin");
     }
 
@@ -136,51 +117,53 @@ function TypedArrayCopyWithin(target, st
 // ES6 draft rev30 (2014/12/24) 22.2.3.6 %TypedArray%.prototype.entries()
 function TypedArrayEntries() {
     // Step 1.
     var O = this;
 
     // We need to be a bit careful here, because in the Xray case we want to
     // create the iterator in our current compartment.
     //
-    // Before doing that, though, we want to check that we have a typed array
-    // and it does not have a detached array buffer.  We do the latter by just
-    // calling GetAttachedArrayBuffer() and letting it throw if there isn't one.
-    // In the case when we're not sure we have a typed array (e.g. we might have
-    // a cross-compartment wrapper for one), we can go ahead and call
-    // GetAttachedArrayBuffer via IsTypedArrayEnsuringArrayBuffer; that will
-    // throw if we're not actually a wrapped typed array, or if we have a
-    // detached array buffer.
+    // Before doing that, though, we want to check that we have a typed
+    // array and it does not have a detached array buffer.  We do the latter by
+    // just calling GetAttachedArrayBuffer() and letting it throw if there isn't
+    // one.  In the case when we're not sure we have a typed array (e.g. we
+    // might have a cross-compartment wrapper for one), we can go ahead and call
+    // GetAttachedArrayBuffer via CallTypedArrayMethodIfWrapped; that will throw
+    // if we're not actually a wrapped typed array, or if we have a detached
+    // array buffer.
 
-    // Step 2-6.
-    IsTypedArrayEnsuringArrayBuffer(O);
+    // Step 2-3.
+    if (!IsObject(O) || !IsTypedArray(O)) {
+        // And also step 4-6.
+        callFunction(CallTypedArrayMethodIfWrapped, O, O, "GetAttachedArrayBuffer");
+    } else {
+        // Step 4-6.
+        GetAttachedArrayBuffer(O);
+    }
 
     // Step 7.
     return CreateArrayIterator(O, ITEM_KIND_KEY_AND_VALUE);
 }
 
 // ES6 draft rev30 (2014/12/24) 22.2.3.7 %TypedArray%.prototype.every(callbackfn[, thisArg]).
 function TypedArrayEvery(callbackfn, thisArg = undefined) {
+    // This function is not generic.
+    if (!IsObject(this) || !IsTypedArray(this)) {
+        return callFunction(CallTypedArrayMethodIfWrapped, this, callbackfn, thisArg,
+                            "TypedArrayEvery");
+    }
+
+    GetAttachedArrayBuffer(this);
+
     // Steps 1-2.
     var O = this;
 
-    // This function is not generic.
-    // We want to make sure that we have an attached buffer, per spec prose.
-    var isTypedArray = IsTypedArrayEnsuringArrayBuffer(O);
-
-    // If we got here, `this` is either a typed array or a cross-compartment
-    // wrapper for one.
-
     // Steps 3-5.
-    var len;
-    if (isTypedArray) {
-        len = TypedArrayLength(O);
-    } else {
-        len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
-    }
+    var len = TypedArrayLength(O);
 
     // Step 6.
     if (arguments.length === 0)
         ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.every");
     if (!IsCallable(callbackfn))
         ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
 
     // Step 7.
@@ -247,29 +230,25 @@ function TypedArrayFill(value, start = 0
 
 // ES6 draft 32 (2015-02-02) 22.2.3.9 %TypedArray%.prototype.filter(callbackfn[, thisArg])
 function TypedArrayFilter(callbackfn, thisArg = undefined) {
     // Step 1.
     var O = this;
 
     // Steps 2-3.
     // This function is not generic.
-    // We want to make sure that we have an attached buffer, per spec prose.
-    var isTypedArray = IsTypedArrayEnsuringArrayBuffer(O);
+    if (!IsObject(O) || !IsTypedArray(O)) {
+        return callFunction(CallTypedArrayMethodIfWrapped, this, callbackfn, thisArg,
+                           "TypedArrayFilter");
+    }
 
-    // If we got here, `this` is either a typed array or a cross-compartment
-    // wrapper for one.
+    GetAttachedArrayBuffer(O);
 
     // Step 4.
-    var len;
-    if (isTypedArray) {
-        len = TypedArrayLength(O);
-    } else {
-        len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
-    }
+    var len = TypedArrayLength(O);
 
     // Step 5.
     if (arguments.length === 0)
         ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.filter");
     if (!IsCallable(callbackfn))
         ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
 
     // Step 6.
@@ -312,33 +291,29 @@ function TypedArrayFilter(callbackfn, th
     }
 
     // Step 18.
     return A;
 }
 
 // ES6 draft rev28 (2014/10/14) 22.2.3.10 %TypedArray%.prototype.find(predicate[, thisArg]).
 function TypedArrayFind(predicate, thisArg = undefined) {
+    // This function is not generic.
+    if (!IsObject(this) || !IsTypedArray(this)) {
+        return callFunction(CallTypedArrayMethodIfWrapped, this, predicate, thisArg,
+                            "TypedArrayFind");
+    }
+
+    GetAttachedArrayBuffer(this);
+
     // Steps 1-2.
     var O = this;
 
-    // This function is not generic.
-    // We want to make sure that we have an attached buffer, per spec prose.
-    var isTypedArray = IsTypedArrayEnsuringArrayBuffer(O);
-
-    // If we got here, `this` is either a typed array or a cross-compartment
-    // wrapper for one.
-
     // Steps 3-5.
-    var len;
-    if (isTypedArray) {
-        len = TypedArrayLength(O);
-    } else {
-        len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
-    }
+    var len = TypedArrayLength(O);
 
     // Step 6.
     if (arguments.length === 0)
         ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.find");
     if (!IsCallable(predicate))
         ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, predicate));
 
     // Step 7.
@@ -355,33 +330,29 @@ function TypedArrayFind(predicate, thisA
     }
 
     // Step 10.
     return undefined;
 }
 
 // ES6 draft rev28 (2014/10/14) 22.2.3.11 %TypedArray%.prototype.findIndex(predicate[, thisArg]).
 function TypedArrayFindIndex(predicate, thisArg = undefined) {
+    // This function is not generic.
+    if (!IsObject(this) || !IsTypedArray(this)) {
+        return callFunction(CallTypedArrayMethodIfWrapped, this, predicate, thisArg,
+                            "TypedArrayFindIndex");
+    }
+
+    GetAttachedArrayBuffer(this);
+
     // Steps 1-2.
     var O = this;
 
-    // This function is not generic.
-    // We want to make sure that we have an attached buffer, per spec prose.
-    var isTypedArray = IsTypedArrayEnsuringArrayBuffer(O);
-
-    // If we got here, `this` is either a typed array or a cross-compartment
-    // wrapper for one.
-
     // Steps 3-5.
-    var len;
-    if (isTypedArray) {
-        len = TypedArrayLength(O);
-    } else {
-        len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
-    }
+    var len = TypedArrayLength(O);
 
     // Step 6.
     if (arguments.length === 0)
         ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.findIndex");
     if (!IsCallable(predicate))
         ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, predicate));
 
     // Step 7.
@@ -396,33 +367,29 @@ function TypedArrayFindIndex(predicate, 
     }
 
     // Step 10.
     return -1;
 }
 
 // ES6 draft rev31 (2015-01-15) 22.1.3.10 %TypedArray%.prototype.forEach(callbackfn[,thisArg])
 function TypedArrayForEach(callbackfn, thisArg = undefined) {
+    // This function is not generic.
+    if (!IsObject(this) || !IsTypedArray(this)) {
+        return callFunction(CallTypedArrayMethodIfWrapped, this, callbackfn, thisArg,
+                            "TypedArrayForEach");
+    }
+
+    GetAttachedArrayBuffer(this);
+
     // Step 1-2.
     var O = this;
 
-    // This function is not generic.
-    // We want to make sure that we have an attached buffer, per spec prose.
-    var isTypedArray = IsTypedArrayEnsuringArrayBuffer(O);
-
-    // If we got here, `this` is either a typed array or a cross-compartment
-    // wrapper for one.
-
     // Step 3-4.
-    var len;
-    if (isTypedArray) {
-        len = TypedArrayLength(O);
-    } else {
-        len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
-    }
+    var len = TypedArrayLength(O);
 
     // Step 5.
     if (arguments.length === 0)
         ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'TypedArray.prototype.forEach');
     if (!IsCallable(callbackfn))
         ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
 
     // Step 6.
@@ -544,17 +511,20 @@ function TypedArrayJoin(separator) {
 // ES6 draft (2016/1/11) 22.2.3.15 %TypedArray%.prototype.keys()
 function TypedArrayKeys() {
     // Step 1.
     var O = this;
 
     // See the big comment in TypedArrayEntries for what we're doing here.
 
     // Step 2.
-    IsTypedArrayEnsuringArrayBuffer(O);
+    if (!IsObject(O) || !IsTypedArray(O))
+        callFunction(CallTypedArrayMethodIfWrapped, O, O, "GetAttachedArrayBuffer");
+    else
+        GetAttachedArrayBuffer(O);
 
     // Step 3.
     return CreateArrayIterator(O, ITEM_KIND_KEY);
 }
 
 // ES6 draft rev29 (2014/12/06) 22.2.3.16 %TypedArray%.prototype.lastIndexOf(searchElement [,fromIndex]).
 function TypedArrayLastIndexOf(searchElement, fromIndex = undefined) {
     // This function is not generic.
@@ -594,29 +564,25 @@ function TypedArrayLastIndexOf(searchEle
 
 // ES6 draft rev32 (2015-02-02) 22.2.3.18 %TypedArray%.prototype.map(callbackfn [, thisArg]).
 function TypedArrayMap(callbackfn, thisArg = undefined) {
     // Step 1.
     var O = this;
 
     // Steps 2-3.
     // This function is not generic.
-    // We want to make sure that we have an attached buffer, per spec prose.
-    var isTypedArray = IsTypedArrayEnsuringArrayBuffer(O);
+    if (!IsObject(O) || !IsTypedArray(O)) {
+        return callFunction(CallTypedArrayMethodIfWrapped, this, callbackfn, thisArg,
+                            "TypedArrayMap");
+    }
 
-    // If we got here, `this` is either a typed array or a cross-compartment
-    // wrapper for one.
+    GetAttachedArrayBuffer(O);
 
     // Step 4.
-    var len;
-    if (isTypedArray) {
-        len = TypedArrayLength(O);
-    } else {
-        len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
-    }
+    var len = TypedArrayLength(O);
 
     // Step 5.
     if (arguments.length === 0)
         ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, '%TypedArray%.prototype.map');
     if (!IsCallable(callbackfn))
         ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
 
     // Step 6.
@@ -640,33 +606,27 @@ function TypedArrayMap(callbackfn, thisA
     }
 
     // Step 14.
     return A;
 }
 
 // ES6 draft rev30 (2014/12/24) 22.2.3.19 %TypedArray%.prototype.reduce(callbackfn[, initialValue]).
 function TypedArrayReduce(callbackfn/*, initialValue*/) {
+    // This function is not generic.
+    if (!IsObject(this) || !IsTypedArray(this))
+        return callFunction(CallTypedArrayMethodIfWrapped, this, callbackfn, "TypedArrayReduce");
+
+    GetAttachedArrayBuffer(this);
+
     // Steps 1-2.
     var O = this;
 
-    // This function is not generic.
-    // We want to make sure that we have an attached buffer, per spec prose.
-    var isTypedArray = IsTypedArrayEnsuringArrayBuffer(O);
-
-    // If we got here, `this` is either a typed array or a cross-compartment
-    // wrapper for one.
-
     // Steps 3-5.
-    var len;
-    if (isTypedArray) {
-        len = TypedArrayLength(O);
-    } else {
-        len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
-    }
+    var len = TypedArrayLength(O);
 
     // Step 6.
     if (arguments.length === 0)
         ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.reduce");
     if (!IsCallable(callbackfn))
         ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
 
     // Step 7.
@@ -687,33 +647,27 @@ function TypedArrayReduce(callbackfn/*, 
     }
 
     // Step 12.
     return accumulator;
 }
 
 // ES6 draft rev30 (2014/12/24) 22.2.3.20 %TypedArray%.prototype.reduceRight(callbackfn[, initialValue]).
 function TypedArrayReduceRight(callbackfn/*, initialValue*/) {
+    // This function is not generic.
+    if (!IsObject(this) || !IsTypedArray(this))
+        return callFunction(CallTypedArrayMethodIfWrapped, this, callbackfn, "TypedArrayReduceRight");
+
+    GetAttachedArrayBuffer(this);
+
     // Steps 1-2.
     var O = this;
 
-    // This function is not generic.
-    // We want to make sure that we have an attached buffer, per spec prose.
-    var isTypedArray = IsTypedArrayEnsuringArrayBuffer(O);
-
-    // If we got here, `this` is either a typed array or a cross-compartment
-    // wrapper for one.
-
     // Steps 3-5.
-    var len;
-    if (isTypedArray) {
-        len = TypedArrayLength(O);
-    } else {
-        len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
-    }
+    var len = TypedArrayLength(O);
 
     // Step 6.
     if (arguments.length === 0)
         ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.reduceRight");
     if (!IsCallable(callbackfn))
         ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
 
     // Step 7.
@@ -954,33 +908,29 @@ function TypedArraySlice(start, end) {
     }
 
     // Step 19.
     return A;
 }
 
 // ES6 draft rev30 (2014/12/24) 22.2.3.25 %TypedArray%.prototype.some(callbackfn[, thisArg]).
 function TypedArraySome(callbackfn, thisArg = undefined) {
+    // This function is not generic.
+    if (!IsObject(this) || !IsTypedArray(this)) {
+        return callFunction(CallTypedArrayMethodIfWrapped, this, callbackfn, thisArg,
+                            "TypedArraySome");
+    }
+
+    GetAttachedArrayBuffer(this);
+
     // Steps 1-2.
     var O = this;
 
-    // This function is not generic.
-    // We want to make sure that we have an attached buffer, per spec prose.
-    var isTypedArray = IsTypedArrayEnsuringArrayBuffer(O);
-
-    // If we got here, `this` is either a typed array or a cross-compartment
-    // wrapper for one.
-
     // Steps 3-5.
-    var len;
-    if (isTypedArray) {
-        len = TypedArrayLength(O);
-    } else {
-        len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
-    }
+    var len = TypedArrayLength(O);
 
     // Step 6.
     if (arguments.length === 0)
         ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.some");
     if (!IsCallable(callbackfn))
         ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
 
     // Step 7.
@@ -1031,22 +981,26 @@ function TypedArrayCompare(x, y) {
     if (Number_isNaN(x) || Number_isNaN(y))
         return Number_isNaN(x) ? 1 : -1;
 
 }
 
 // ES6 draft 20151210 22.2.3.26 %TypedArray%.prototype.sort ( comparefn ).
 function TypedArraySort(comparefn) {
     // This function is not generic.
+    if (!IsObject(this) || !IsTypedArray(this)) {
+        return callFunction(CallTypedArrayMethodIfWrapped, this, comparefn,
+                            "TypedArraySort");
+    }
 
     // Step 1.
     var obj = this;
 
     // Step 2.
-    var isTypedArray = IsTypedArrayEnsuringArrayBuffer(obj);
+    var buffer = GetAttachedArrayBuffer(obj);
 
     // Step 3.
     var len = TypedArrayLength(obj);
 
     if (comparefn === undefined) {
         comparefn = TypedArrayCompare;
         // CountingSort doesn't invoke the comparefn
         if (IsUint8TypedArray(obj)) {
@@ -1059,40 +1013,30 @@ function TypedArraySort(comparefn) {
             return RadixSort(obj, len, 2 /* nbytes */, true /* signed */, false /* floating */, comparefn);
         } else if (IsUint32TypedArray(obj)) {
             return RadixSort(obj, len, 4 /* nbytes */, false /* signed */, false /* floating */, comparefn);
         } else if (IsInt32TypedArray(obj)) {
             return RadixSort(obj, len, 4 /* nbytes */, true /* signed */, false /* floating */, comparefn);
         } else if (IsFloat32TypedArray(obj)) {
             return RadixSort(obj, len, 4 /* nbytes */, true /* signed */, true /* floating */, comparefn);
         }
-    }
-
-    // To satisfy step 2 from TypedArray SortCompare described in 22.2.3.26
-    // the user supplied comparefn is wrapped.
-    var wrappedCompareFn = comparefn;
-    comparefn = function(x, y) {
-        // Step a.
-        var v = wrappedCompareFn(x, y);
-        // Step b.
-        var bufferDetached;
-        if (isTypedArray) {
-            bufferDetached = IsDetachedBuffer(buffer);
-        } else {
-            // This is totally cheating and only works because we know `this`
-            // and `buffer` are same-compartment".
-            bufferDetached = callFunction(CallTypedArrayMethodIfWrapped, this,
-                                          buffer, "IsDetachedBuffer");
+        // To satisfy step 2 from TypedArray SortCompare described in 22.2.3.26
+        // the user supplied comparefn is wrapped.
+        var wrappedCompareFn = comparefn;
+        comparefn = function(x, y) {
+            // Step a.
+            var v = wrappedCompareFn(x, y);
+            // Step b.
+            if (IsDetachedBuffer(buffer))
+                ThrowTypeError(JSMSG_TYPED_ARRAY_DETACHED);
+            // Step c. is redundant, see:
+            // https://bugzilla.mozilla.org/show_bug.cgi?id=1121937#c36
+            // Step d.
+            return v;
         }
-        if (bufferDetached)
-            ThrowTypeError(JSMSG_TYPED_ARRAY_DETACHED);
-        // Step c. is redundant, see:
-        // https://bugzilla.mozilla.org/show_bug.cgi?id=1121937#c36
-        // Step d.
-        return v;
     }
 
     return QuickSort(obj, len, comparefn);
 }
 
 // ES6 draft 20150304 %TypedArray%.prototype.subarray
 function TypedArraySubarray(begin, end) {
     // Step 1.
@@ -1140,17 +1084,25 @@ function TypedArraySubarray(begin, end) 
 }
 
 // ES6 draft rev30 (2014/12/24) 22.2.3.30 %TypedArray%.prototype.values()
 function TypedArrayValues() {
     // Step 1.
     var O = this;
 
     // See the big comment in TypedArrayEntries for what we're doing here.
-    IsTypedArrayEnsuringArrayBuffer(O);
+
+    // Steps 2-6.
+    if (!IsObject(O) || !IsTypedArray(O)) {
+        // And also steps 4-6.
+        callFunction(CallTypedArrayMethodIfWrapped, O, O, "GetAttachedArrayBuffer");
+    } else {
+        // Steps 4-6.
+        GetAttachedArrayBuffer(O);
+    }
 
     // Step 7.
     return CreateArrayIterator(O, ITEM_KIND_VALUE);
 }
 _SetCanonicalName(TypedArrayValues, "values");
 
 // Proposed for ES7:
 // https://github.com/tc39/Array.prototype.includes/blob/7c023c19a0/spec.md
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -1539,41 +1539,26 @@ js::IsCallSelfHostedNonGenericMethod(Nat
 bool
 js::ReportIncompatibleSelfHostedMethod(JSContext* cx, const CallArgs& args)
 {
     // The contract for this function is the same as CallSelfHostedNonGenericMethod.
     // The normal ReportIncompatible function doesn't work for selfhosted functions,
     // because they always call the different CallXXXMethodIfWrapped methods,
     // which would be reported as the called function instead.
 
-    // Lookup the selfhosted method that was invoked.  But skip over
-    // IsTypedArrayEnsuringArrayBuffer frames, because those are never the
-    // actual self-hosted callee from external code.  We can't just skip
-    // self-hosted things until we find a non-self-hosted one because of cases
-    // like array.sort(somethingSelfHosted), where we want to report the error
-    // in the somethingSelfHosted, not in the sort() call.
+    // Lookup the selfhosted method that was invoked.
     ScriptFrameIter iter(cx);
     MOZ_ASSERT(iter.isFunctionFrame());
 
-    while (!iter.done()) {
-        MOZ_ASSERT(iter.callee(cx)->isSelfHostedOrIntrinsic() &&
-                   !iter.callee(cx)->isBoundFunction());
-        JSAutoByteString funNameBytes;
-        const char* funName = GetFunctionNameBytes(cx, iter.callee(cx), &funNameBytes);
-        if (!funName)
-            return false;
-        if (strcmp(funName, "IsTypedArrayEnsuringArrayBuffer") != 0) {
-            JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_METHOD,
-                                 funName, "method", InformalValueTypeName(args.thisv()));
-            return false;
-        }
-        ++iter;
+    JSAutoByteString funNameBytes;
+    if (const char* funName = GetFunctionNameBytes(cx, iter.callee(cx), &funNameBytes)) {
+        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_METHOD,
+                             funName, "method", InformalValueTypeName(args.thisv()));
     }
 
-    MOZ_ASSERT_UNREACHABLE("How did we not find a useful self-hosted frame?");
     return false;
 }
 
 // ES6, 25.4.1.6.
 static bool
 intrinsic_EnqueuePromiseJob(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
@@ -1676,21 +1661,19 @@ intrinsic_IsConstructing(JSContext* cx, 
 }
 
 static bool
 intrinsic_ConstructorForTypedArray(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 1);
     MOZ_ASSERT(args[0].isObject());
+    MOZ_ASSERT(args[0].toObject().is<TypedArrayObject>());
 
     RootedObject object(cx, &args[0].toObject());
-    object = CheckedUnwrap(object);
-    MOZ_ASSERT(object->is<TypedArrayObject>());
-
     JSProtoKey protoKey = StandardProtoKeyOrNull(object);
     MOZ_ASSERT(protoKey);
 
     // While it may seem like an invariant that in any compartment,
     // seeing a typed array object implies that the TypedArray constructor
     // for that type is initialized on the compartment's global, this is not
     // the case. When we construct a typed array given a cross-compartment
     // ArrayBuffer, we put the constructed TypedArray in the same compartment
--- a/js/xpconnect/tests/chrome/test_xrayToJS.xul
+++ b/js/xpconnect/tests/chrome/test_xrayToJS.xul
@@ -434,57 +434,16 @@ https://bugzilla.mozilla.org/show_bug.cg
     arraysEqual([...arrayLike.entries()], [...equivalentArray.entries()],
                 \`\${reason}; entries\`);
     arraysEqual([...arrayLike.keys()], [...equivalentArray.keys()],
                 \`\${reason}; keys\`);
     if (arrayLike.values) {
       arraysEqual([...arrayLike.values()], equivalentArray,
                   \`\${reason}; values\`);
     }
-
-    var forEachCopy = [];
-    arrayLike.forEach(function(arg) { forEachCopy.push(arg); });
-    arraysEqual(forEachCopy, equivalentArray, \`\${reason}; forEach copy\`);
-
-    var everyCopy = [];
-    arrayLike.every(function(arg) { everyCopy.push(arg); return true; });
-    arraysEqual(everyCopy, equivalentArray, \`\${reason}; every() copy\`);
-
-    var filterCopy = [];
-    var filterResult = arrayLike.filter(function(arg) {
-      filterCopy.push(arg);
-      return true;
-    });
-    arraysEqual(filterCopy, equivalentArray, \`\${reason}; filter copy\`);
-    arraysEqual([...filterResult], equivalentArray, \`\${reason}; filter result\`);
-
-    var findCopy = [];
-    arrayLike.find(function(arg) { findCopy.push(arg); return false; });
-    arraysEqual(findCopy, equivalentArray, \`\${reason}; find() copy\`);
-
-    var findIndexCopy = [];
-    arrayLike.findIndex(function(arg) { findIndexCopy.push(arg); return false; });
-    arraysEqual(findIndexCopy, equivalentArray, \`\${reason}; findIndex() copy\`);
-
-    var mapCopy = [];
-    var mapResult = arrayLike.map(function(arg) { mapCopy.push(arg); return arg});
-    arraysEqual(mapCopy, equivalentArray, \`\${reason}; map() copy\`);
-    arraysEqual([...mapResult], equivalentArray, \`\${reason}; map() result\`);
-
-    var reduceCopy = [];
-    arrayLike.reduce(function(_, arg) { reduceCopy.push(arg); }, 0);
-    arraysEqual(reduceCopy, equivalentArray, \`\${reason}; reduce() copy\`);
-
-    var reduceRightCopy = [];
-    arrayLike.reduceRight(function(_, arg) { reduceRightCopy.unshift(arg); }, 0);
-    arraysEqual(reduceRightCopy, equivalentArray, \`\${reason}; reduceRight() copy\`);
-
-    var someCopy = [];
-    arrayLike.some(function(arg) { someCopy.push(arg); return false; });
-    arraysEqual(someCopy, equivalentArray, \`\${reason}; some() copy\`);
   }`;
   eval(testArrayIteratorsSource);
 
   function testDate() {
     // toGMTString is handled oddly in the engine. We don't bother to support
     // it over Xrays.
     let propsToSkip = ['toGMTString'];