Bug 800915 - Remove the cx parameter and simplify various APIs. r=sfink,bz
authorBobby Holley <bobbyholley@gmail.com>
Wed, 14 Nov 2012 09:56:26 -0800
changeset 113259 f8620fc3f18fd2db2b5c844d639431571038fa0c
parent 113258 850c0b306b6e64bd976e019a9e64cfc2a3f87fa1
child 113260 5f0036778492a1d31e1c8331e4d48ab0e44f38e7
push id1200
push userryanvm@gmail.com
push dateSat, 17 Nov 2012 18:32:07 +0000
treeherderfx-team@4639da479a93 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink, bz
bugs800915
milestone19.0a1
Bug 800915 - Remove the cx parameter and simplify various APIs. r=sfink,bz If callers want to throw, it's now their responsibility.
content/base/src/nsContentUtils.cpp
content/base/src/nsDOMBlobBuilder.cpp
content/base/src/nsDOMDataChannel.cpp
content/base/src/nsDOMFileReader.cpp
content/base/src/nsXMLHttpRequest.cpp
content/canvas/src/CanvasRenderingContext2D.cpp
content/canvas/src/WebGLContextGL.cpp
content/events/src/nsDOMNotifyAudioAvailableEvent.cpp
content/html/content/src/nsHTMLAudioElement.cpp
dom/bindings/BindingUtils.cpp
dom/bindings/BindingUtils.h
dom/bindings/Codegen.py
dom/bindings/TypedArray.h
dom/file/LockedFile.cpp
dom/network/src/TCPSocketChild.cpp
dom/network/src/TCPSocketParent.cpp
dom/plugins/base/nsJSNPRuntime.cpp
dom/system/gonk/SystemWorkerManager.cpp
dom/workers/FileReaderSync.cpp
dom/workers/ImageData.cpp
dom/workers/XMLHttpRequest.cpp
js/src/ctypes/CTypes.cpp
js/src/jsapi-tests/testArrayBuffer.cpp
js/src/jsapi-tests/testTypedArrays.cpp
js/src/jsclone.cpp
js/src/jsfriendapi.h
js/src/jsfun.cpp
js/src/jstypedarray.cpp
js/src/jswrapper.cpp
js/src/jswrapper.h
js/src/vm/Debugger.cpp
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/XPCConvert.cpp
js/xpconnect/src/xpcprivate.h
js/xpconnect/wrappers/AccessCheck.cpp
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -6182,18 +6182,18 @@ nsContentUtils::CreateArrayBuffer(JSCont
 
   int32_t dataLen = aData.Length();
   *aResult = JS_NewArrayBuffer(aCx, dataLen);
   if (!*aResult) {
     return NS_ERROR_FAILURE;
   }
 
   if (dataLen > 0) {
-    NS_ASSERTION(JS_IsArrayBufferObject(*aResult, aCx), "What happened?");
-    memcpy(JS_GetArrayBufferData(*aResult, aCx), aData.BeginReading(), dataLen);
+    NS_ASSERTION(JS_IsArrayBufferObject(*aResult), "What happened?");
+    memcpy(JS_GetArrayBufferData(*aResult), aData.BeginReading(), dataLen);
   }
 
   return NS_OK;
 }
 
 // Initial implementation: only stores to RAM, not file
 // TODO: bug 704447: large file support
 nsresult
--- a/content/base/src/nsDOMBlobBuilder.cpp
+++ b/content/base/src/nsDOMBlobBuilder.cpp
@@ -229,22 +229,22 @@ nsDOMMultipartFile::InitInternal(JSConte
               subBlobs = file->GetSubBlobs();
           if (subBlobs) {
             blobSet.AppendBlobs(*subBlobs);
           } else {
             blobSet.AppendBlob(blob);
           }
           continue;
         }
-        if (JS_IsArrayBufferViewObject(&obj, aCx)) {
-          blobSet.AppendVoidPtr(JS_GetArrayBufferViewData(&obj, aCx),
-                                JS_GetArrayBufferViewByteLength(&obj, aCx));
+        if (JS_IsArrayBufferViewObject(&obj)) {
+          blobSet.AppendVoidPtr(JS_GetArrayBufferViewData(&obj),
+                                JS_GetArrayBufferViewByteLength(&obj));
           continue;
         }
-        if (JS_IsArrayBufferObject(&obj, aCx)) {
+        if (JS_IsArrayBufferObject(&obj)) {
           blobSet.AppendArrayBuffer(&obj, aCx);
           continue;
         }
         // neither Blob nor ArrayBuffer(View)
       } else if (element.isString()) {
         blobSet.AppendString(element.toString(), nativeEOL, aCx);
         continue;
       }
@@ -316,11 +316,11 @@ BlobSet::AppendBlobs(const nsTArray<nsCO
   mBlobs.AppendElements(aBlob);
 
   return NS_OK;
 }
 
 nsresult
 BlobSet::AppendArrayBuffer(JSObject* aBuffer, JSContext *aCx)
 {
-  return AppendVoidPtr(JS_GetArrayBufferData(aBuffer, aCx),
-                       JS_GetArrayBufferByteLength(aBuffer, aCx));
+  return AppendVoidPtr(JS_GetArrayBufferData(aBuffer),
+                       JS_GetArrayBufferByteLength(aBuffer));
 }
--- a/content/base/src/nsDOMDataChannel.cpp
+++ b/content/base/src/nsDOMDataChannel.cpp
@@ -312,19 +312,19 @@ nsDOMDataChannel::GetSendParams(nsIVaria
     nsMemory::Free(iid);
 
     // ArrayBuffer?
     jsval realVal;
     JSObject* obj;
     nsresult rv = aData->GetAsJSVal(&realVal);
     if (NS_SUCCEEDED(rv) && !JSVAL_IS_PRIMITIVE(realVal) &&
         (obj = JSVAL_TO_OBJECT(realVal)) &&
-        (JS_IsArrayBufferObject(obj, aCx))) {
-      int32_t len = JS_GetArrayBufferByteLength(obj, aCx);
-      char* data = reinterpret_cast<char*>(JS_GetArrayBufferData(obj, aCx));
+        (JS_IsArrayBufferObject(obj))) {
+      int32_t len = JS_GetArrayBufferByteLength(obj);
+      char* data = reinterpret_cast<char*>(JS_GetArrayBufferData(obj));
 
       aStringOut.Assign(data, len);
       aIsBinary = true;
       aOutgoingLength = len;
       return NS_OK;
     }
 
     // Blob?
--- a/content/base/src/nsDOMFileReader.cpp
+++ b/content/base/src/nsDOMFileReader.cpp
@@ -304,17 +304,17 @@ nsDOMFileReader::DoOnDataAvailable(nsIRe
 
     uint32_t bytesRead = 0;
     aInputStream->ReadSegments(ReadFuncBinaryString, buf + oldLen, aCount,
                                &bytesRead);
     NS_ASSERTION(bytesRead == aCount, "failed to read data");
   }
   else if (mDataFormat == FILE_AS_ARRAYBUFFER) {
     uint32_t bytesRead = 0;
-    aInputStream->Read((char*)JS_GetArrayBufferData(mResultArrayBuffer, NULL) + aOffset,
+    aInputStream->Read((char*)JS_GetArrayBufferData(mResultArrayBuffer) + aOffset,
                        aCount, &bytesRead);
     NS_ASSERTION(bytesRead == aCount, "failed to read data");
   }
   else {
     //Update memory buffer to reflect the contents of the file
     if (aOffset + aCount > UINT32_MAX) {
       // PR_Realloc doesn't support over 4GB memory size even if 64-bit OS
       return NS_ERROR_OUT_OF_MEMORY;
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -2664,18 +2664,18 @@ GetRequestBody(nsIVariant* aBody, nsIInp
         return NS_ERROR_FAILURE;
       }
     }
 
     nsresult rv = aBody->GetAsJSVal(&realVal);
     if (NS_SUCCEEDED(rv) && !JSVAL_IS_PRIMITIVE(realVal)) {
       JSObject *obj = JSVAL_TO_OBJECT(realVal);
       ac.construct(cx, obj);
-      if (JS_IsArrayBufferObject(obj, cx)) {
-          ArrayBuffer buf(cx, obj);
+      if (JS_IsArrayBufferObject(obj)) {
+          ArrayBuffer buf(obj);
           return GetRequestBody(&buf, aResult, aContentLength, aContentType, aCharset);
       }
     }
   }
   else if (dataType == nsIDataType::VTYPE_VOID ||
            dataType == nsIDataType::VTYPE_EMPTY) {
     // Makes us act as if !aBody, don't upload anything
     aContentType.AssignLiteral("text/plain");
--- a/content/canvas/src/CanvasRenderingContext2D.cpp
+++ b/content/canvas/src/CanvasRenderingContext2D.cpp
@@ -3488,17 +3488,17 @@ CanvasRenderingContext2D::GetImageDataAr
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   if (mZero) {
     *aRetval = darray;
     return NS_OK;
   }
 
-  uint8_t* data = JS_GetUint8ClampedArrayData(darray, aCx);
+  uint8_t* data = JS_GetUint8ClampedArrayData(darray);
 
   IntRect srcRect(0, 0, mWidth, mHeight);
   IntRect destRect(aX, aY, aWidth, aHeight);
 
   IntRect srcReadRect = srcRect.Intersect(destRect);
   IntRect dstWriteRect = srcReadRect;
   dstWriteRect.MoveBy(-aX, -aY);
 
@@ -3600,17 +3600,17 @@ CanvasRenderingContext2D::PutImageData(J
                                        ImageData& imageData, double dx,
                                        double dy, ErrorResult& error)
 {
   if (!FloatValidate(dx, dy)) {
     error.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
     return;
   }
 
-  dom::Uint8ClampedArray arr(cx, imageData.GetDataObject());
+  dom::Uint8ClampedArray arr(imageData.GetDataObject());
 
   error = PutImageData_explicit(JS_DoubleToInt32(dx), JS_DoubleToInt32(dy),
                                 imageData.Width(), imageData.Height(),
                                 arr.Data(), arr.Length(), false, 0, 0, 0, 0);
 }
 
 void
 CanvasRenderingContext2D::PutImageData(JSContext* cx,
@@ -3620,17 +3620,17 @@ CanvasRenderingContext2D::PutImageData(J
                                        double dirtyHeight,
                                        ErrorResult& error)
 {
   if (!FloatValidate(dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight)) {
     error.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
     return;
   }
 
-  dom::Uint8ClampedArray arr(cx, imageData.GetDataObject());
+  dom::Uint8ClampedArray arr(imageData.GetDataObject());
 
   error = PutImageData_explicit(JS_DoubleToInt32(dx), JS_DoubleToInt32(dy),
                                 imageData.Width(), imageData.Height(),
                                 arr.Data(), arr.Length(), true,
                                 JS_DoubleToInt32(dirtyX),
                                 JS_DoubleToInt32(dirtyY),
                                 JS_DoubleToInt32(dirtyWidth),
                                 JS_DoubleToInt32(dirtyHeight));
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -3152,18 +3152,18 @@ WebGLContext::ReadPixels(WebGLint x, Web
     if (!pixels)
         return ErrorInvalidValue("readPixels: null destination buffer");
 
     const WebGLRectangleObject *framebufferRect = FramebufferRectangleObject();
     WebGLsizei framebufferWidth = framebufferRect ? framebufferRect->Width() : 0;
     WebGLsizei framebufferHeight = framebufferRect ? framebufferRect->Height() : 0;
 
     void* data = pixels->Data();
-    uint32_t dataByteLen = JS_GetTypedArrayByteLength(pixels->Obj(), NULL);
-    int dataType = JS_GetTypedArrayType(pixels->Obj(), NULL);
+    uint32_t dataByteLen = JS_GetTypedArrayByteLength(pixels->Obj());
+    int dataType = JS_GetTypedArrayType(pixels->Obj());
 
     uint32_t channels = 0;
 
     // Check the format param
     switch (format) {
         case LOCAL_GL_ALPHA:
             channels = 1;
             break;
@@ -4868,34 +4868,34 @@ WebGLContext::TexImage2D(JSContext* cx, 
                          WebGLenum type, ArrayBufferView *pixels, ErrorResult& rv)
 {
     if (!IsContextStable())
         return;
 
     return TexImage2D_base(target, level, internalformat, width, height, 0, border, format, type,
                            pixels ? pixels->Data() : 0,
                            pixels ? pixels->Length() : 0,
-                           pixels ? (int)JS_GetTypedArrayType(pixels->Obj(), cx) : -1,
+                           pixels ? (int)JS_GetTypedArrayType(pixels->Obj()) : -1,
                            WebGLTexelConversions::Auto, false);
 }
 
 void
 WebGLContext::TexImage2D(JSContext* cx, WebGLenum target, WebGLint level,
                          WebGLenum internalformat, WebGLenum format,
                          WebGLenum type, ImageData* pixels, ErrorResult& rv)
 {
     if (!IsContextStable())
         return;
 
     if (!pixels) {
         // Spec says to generate an INVALID_VALUE error
         return ErrorInvalidValue("texImage2D: null ImageData");
     }
     
-    Uint8ClampedArray arr(cx, pixels->GetDataObject());
+    Uint8ClampedArray arr(pixels->GetDataObject());
     return TexImage2D_base(target, level, internalformat, pixels->Width(),
                            pixels->Height(), 4*pixels->Width(), 0,
                            format, type, arr.Data(), arr.Length(), -1,
                            WebGLTexelConversions::RGBA8, false);
 }
 
 
 void
@@ -5022,33 +5022,33 @@ WebGLContext::TexSubImage2D(JSContext* c
         return;
 
     if (!pixels)
         return ErrorInvalidValue("texSubImage2D: pixels must not be null!");
 
     return TexSubImage2D_base(target, level, xoffset, yoffset,
                               width, height, 0, format, type,
                               pixels->Data(), pixels->Length(),
-                              JS_GetTypedArrayType(pixels->Obj(), cx),
+                              JS_GetTypedArrayType(pixels->Obj()),
                               WebGLTexelConversions::Auto, false);
 }
 
 void
 WebGLContext::TexSubImage2D(JSContext* cx, WebGLenum target, WebGLint level,
                             WebGLint xoffset, WebGLint yoffset,
                             WebGLenum format, WebGLenum type, ImageData* pixels,
                             ErrorResult& rv)
 {
     if (!IsContextStable())
         return;
 
     if (!pixels)
         return ErrorInvalidValue("texSubImage2D: pixels must not be null!");
 
-    Uint8ClampedArray arr(cx, pixels->GetDataObject());
+    Uint8ClampedArray arr(pixels->GetDataObject());
     return TexSubImage2D_base(target, level, xoffset, yoffset,
                               pixels->Width(), pixels->Height(),
                               4*pixels->Width(), format, type,
                               arr.Data(), arr.Length(),
                               -1,
                               WebGLTexelConversions::RGBA8, false);
 }
 
--- a/content/events/src/nsDOMNotifyAudioAvailableEvent.cpp
+++ b/content/events/src/nsDOMNotifyAudioAvailableEvent.cpp
@@ -81,17 +81,17 @@ nsDOMNotifyAudioAvailableEvent::GetFrame
   // Cache this array so we don't recreate on next call.
   NS_HOLD_JS_OBJECTS(this, nsDOMNotifyAudioAvailableEvent);
 
   mCachedArray = JS_NewFloat32Array(aCx, mFrameBufferLength);
   if (!mCachedArray) {
     NS_DROP_JS_OBJECTS(this, nsDOMNotifyAudioAvailableEvent);
     return NS_ERROR_FAILURE;
   }
-  memcpy(JS_GetFloat32ArrayData(mCachedArray, aCx), mFrameBuffer.get(), mFrameBufferLength * sizeof(float));
+  memcpy(JS_GetFloat32ArrayData(mCachedArray), mFrameBuffer.get(), mFrameBufferLength * sizeof(float));
 
   *aResult = OBJECT_TO_JSVAL(mCachedArray);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMNotifyAudioAvailableEvent::GetTime(float *aRetVal)
 {
--- a/content/html/content/src/nsHTMLAudioElement.cpp
+++ b/content/html/content/src/nsHTMLAudioElement.cpp
@@ -151,41 +151,41 @@ nsHTMLAudioElement::MozWriteAudio(const 
     return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
   }
 
   JSObject* darray = &aData.toObject();
   JS::AutoObjectRooter tvr(aCx);
   JSObject* tsrc = NULL;
 
   // Allow either Float32Array or plain JS Array
-  if (JS_IsFloat32Array(darray, aCx)) {
+  if (JS_IsFloat32Array(darray)) {
     tsrc = darray;
   } else if (JS_IsArrayObject(aCx, darray)) {
     JSObject* nobj = JS_NewFloat32ArrayFromArray(aCx, darray);
     if (!nobj) {
       return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
     }
     tsrc = nobj;
   } else {
     return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
   }
   tvr.setObject(tsrc);
 
-  uint32_t dataLength = JS_GetTypedArrayLength(tsrc, aCx);
+  uint32_t dataLength = JS_GetTypedArrayLength(tsrc);
 
   // Make sure that we are going to write the correct amount of data based
   // on number of channels.
   if (dataLength % mChannels != 0) {
     return NS_ERROR_DOM_INDEX_SIZE_ERR;
   }
 
   // Don't write more than can be written without blocking.
   uint32_t writeLen = NS_MIN(mAudioStream->Available(), dataLength / mChannels);
 
-  float* frames = JS_GetFloat32ArrayData(tsrc, aCx);
+  float* frames = JS_GetFloat32ArrayData(tsrc);
   // Convert the samples back to integers as we are using fixed point audio in
   // the nsAudioStream.
   // This could be optimized to avoid allocation and memcpy when
   // AudioDataValue is 'float', but it's not worth it for this deprecated API.
   nsAutoArrayPtr<AudioDataValue> audioData(new AudioDataValue[writeLen * mChannels]);
   ConvertAudioSamples(frames, audioData.get(), writeLen * mChannels);
   nsresult rv = mAudioStream->Write(audioData.get(), writeLen);
 
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -517,19 +517,21 @@ QueryInterface(JSContext* cx, unsigned a
 {
   JS::Value thisv = JS_THIS(cx, vp);
   if (thisv == JSVAL_NULL)
     return false;
 
   // Get the object. It might be a security wrapper, in which case we do a checked
   // unwrap.
   JSObject* origObj = JSVAL_TO_OBJECT(thisv);
-  JSObject* obj = js::UnwrapObjectChecked(cx, origObj);
-  if (!obj)
+  JSObject* obj = js::UnwrapObjectChecked(origObj);
+  if (!obj) {
+      JS_ReportError(cx, "Permission denied to access object");
       return false;
+  }
 
   nsISupports* native;
   if (!UnwrapDOMObjectToISupports(obj, native)) {
     return Throw<true>(cx, NS_ERROR_FAILURE);
   }
 
   if (argc < 1) {
     return Throw<true>(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -240,17 +240,17 @@ IsArrayLike(JSContext* cx, JSObject* obj
       return false;
     }
 
     ac.construct(cx, obj);
   }
 
   // XXXbz need to detect platform objects (including listbinding
   // ones) with indexGetters here!
-  return JS_IsArrayObject(cx, obj) || JS_IsTypedArrayObject(obj, cx);
+  return JS_IsArrayObject(cx, obj) || JS_IsTypedArrayObject(obj);
 }
 
 inline bool
 IsPlatformObject(JSContext* cx, JSObject* obj)
 {
   // XXXbz Should be treating list-binding objects as platform objects
   // too?  The one consumer so far wants non-array-like platform
   // objects, so listbindings that have an indexGetter should test
@@ -267,17 +267,17 @@ IsPlatformObject(JSContext* cx, JSObject
     obj = xpc::Unwrap(cx, obj, false);
     if (!obj) {
       // Let's say it's not
       return false;
     }
     clasp = js::GetObjectJSClass(obj);
   }
   return IS_WRAPPER_CLASS(js::Valueify(clasp)) || IsDOMClass(clasp) ||
-    JS_IsArrayBufferObject(obj, cx);
+    JS_IsArrayBufferObject(obj);
 }
 
 // U must be something that a T* can be assigned to (e.g. T* or an nsRefPtr<T>).
 template <class T, typename U>
 inline nsresult
 UnwrapObject(JSContext* cx, JSObject* obj, U& value)
 {
   return UnwrapObject<static_cast<prototypes::ID>(
@@ -1309,16 +1309,21 @@ public:
   bool WasPassed() const {
     return !mImpl.empty();
   }
 
   void Construct() {
     mImpl.construct();
   }
 
+  template <class T1>
+  void Construct(const T1 &t1) {
+    mImpl.construct(t1);
+  }
+
   template <class T1, class T2>
   void Construct(const T1 &t1, const T2 &t2) {
     mImpl.construct(t1, t2);
   }
 
   const T& Value() const {
     return mImpl.ref();
   }
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -2584,17 +2584,17 @@ for (uint32_t i = 0; i < length; ++i) {
                 # We don't need a holder in this case
                 holderType = None
                 constructLoc = "(const_cast<Optional<" + name + ">& >(${declName}))"
                 constructMethod = "Construct"
                 constructInternal = "Value"
             else:
                 declType = "NonNull<" + name + ">"
         template = (
-            "%s.%s(cx, &${val}.toObject());\n"
+            "%s.%s(&${val}.toObject());\n"
             "if (!%s.%s().inited()) {\n"
             "%s" # No newline here because onFailureBadType() handles that
             "}\n" %
             (constructLoc, constructMethod, constructLoc, constructInternal,
              CGIndenter(onFailureBadType(failureCode, type.name)).define()))
         nullableTarget = ""
         if type.nullable():
             if isOptional:
--- a/dom/bindings/TypedArray.h
+++ b/dom/bindings/TypedArray.h
@@ -14,21 +14,21 @@ namespace dom {
 
 /*
  * Various typed array classes for argument conversion.  We have a base class
  * that has a way of initializing a TypedArray from an existing typed array, and
  * a subclass of the base class that supports creation of a relevant typed array
  * or array buffer object.
  */
 template<typename T,
-         JSObject* UnboxArray(JSContext*, JSObject*, uint32_t*, T**)>
+         JSObject* UnboxArray(JSObject*, uint32_t*, T**)>
 struct TypedArray_base {
-  TypedArray_base(JSContext* cx, JSObject* obj)
+  TypedArray_base(JSObject* obj)
   {
-    mObj = UnboxArray(cx, obj, &mLength, &mData);
+    mObj = UnboxArray(obj, &mLength, &mData);
   }
 
 private:
   T* mData;
   uint32_t mLength;
   JSObject* mObj;
 
 public:
@@ -49,38 +49,38 @@ public:
   inline JSObject *Obj() const {
     MOZ_ASSERT(inited());
     return mObj;
   }
 };
 
 
 template<typename T,
-         T* GetData(JSObject*, JSContext*),
-         JSObject* UnboxArray(JSContext*, JSObject*, uint32_t*, T**),
+         T* GetData(JSObject*),
+         JSObject* UnboxArray(JSObject*, uint32_t*, T**),
          JSObject* CreateNew(JSContext*, uint32_t)>
 struct TypedArray : public TypedArray_base<T,UnboxArray> {
-  TypedArray(JSContext* cx, JSObject* obj) :
-    TypedArray_base<T,UnboxArray>(cx, obj)
+  TypedArray(JSObject* obj) :
+    TypedArray_base<T,UnboxArray>(obj)
   {}
 
   static inline JSObject*
   Create(JSContext* cx, nsWrapperCache* creator, uint32_t length,
          const T* data = NULL) {
     JSObject* creatorWrapper;
     Maybe<JSAutoCompartment> ac;
     if (creator && (creatorWrapper = creator->GetWrapperPreserveColor())) {
       ac.construct(cx, creatorWrapper);
     }
     JSObject* obj = CreateNew(cx, length);
     if (!obj) {
       return NULL;
     }
     if (data) {
-      T* buf = static_cast<T*>(GetData(obj, cx));
+      T* buf = static_cast<T*>(GetData(obj));
       memcpy(buf, data, length*sizeof(T));
     }
     return obj;
   }
 };
 
 typedef TypedArray<int8_t, JS_GetInt8ArrayData, JS_GetObjectAsInt8Array,
                    JS_NewInt8Array>
--- a/dom/file/LockedFile.cpp
+++ b/dom/file/LockedFile.cpp
@@ -213,19 +213,19 @@ CreateGenericEvent(const nsAString& aTyp
 inline nsresult
 GetInputStreamForJSVal(const jsval& aValue, JSContext* aCx,
                        nsIInputStream** aInputStream, uint64_t* aInputLength)
 {
   nsresult rv;
 
   if (!JSVAL_IS_PRIMITIVE(aValue)) {
     JSObject* obj = JSVAL_TO_OBJECT(aValue);
-    if (JS_IsArrayBufferObject(obj, aCx)) {
-      char* data = reinterpret_cast<char*>(JS_GetArrayBufferData(obj, aCx));
-      uint32_t length = JS_GetArrayBufferByteLength(obj, aCx);
+    if (JS_IsArrayBufferObject(obj)) {
+      char* data = reinterpret_cast<char*>(JS_GetArrayBufferData(obj));
+      uint32_t length = JS_GetArrayBufferByteLength(obj);
 
       rv = NS_NewByteInputStream(aInputStream, data, length,
                                  NS_ASSIGNMENT_COPY);
       NS_ENSURE_SUCCESS(rv, rv);
 
       *aInputLength = length;
 
       return NS_OK;
--- a/dom/network/src/TCPSocketChild.cpp
+++ b/dom/network/src/TCPSocketChild.cpp
@@ -23,17 +23,17 @@ DeserializeUint8Array(JSRawObject aObj,
 {
   JSContext* cx = nsContentUtils::GetSafeJSContext();
   JSAutoRequest ar(cx);
   JSAutoCompartment ac(cx, aObj);
 
   JSObject* obj = JS_NewArrayBuffer(cx, aBuffer.Length());
   if (!obj)
     return false;
-  uint8_t* data = JS_GetArrayBufferData(obj, cx);
+  uint8_t* data = JS_GetArrayBufferData(obj);
   if (!data)
     return false;
   memcpy(data, aBuffer.Elements(), aBuffer.Length());
   JSObject* arr = JS_NewUint8ArrayWithBuffer(cx, obj, 0, aBuffer.Length());
   if (!arr)
     return false;
   *aVal = OBJECT_TO_JSVAL(arr);
   return true;
@@ -182,20 +182,20 @@ TCPSocketChild::Send(const JS::Value& aD
     nsDependentJSString str;
     bool ok = str.init(aCx, jsstr);
     NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
     SendData(str);
 
   } else {
     NS_ENSURE_TRUE(aData.isObject(), NS_ERROR_FAILURE);
     JSObject* obj = &aData.toObject();
-    NS_ENSURE_TRUE(JS_IsTypedArrayObject(obj, aCx), NS_ERROR_FAILURE);
-    NS_ENSURE_TRUE(JS_IsUint8Array(obj, aCx), NS_ERROR_FAILURE);
-    uint32_t nbytes = JS_GetTypedArrayByteLength(obj, aCx);
-    uint8_t* data = JS_GetUint8ArrayData(obj, aCx);
+    NS_ENSURE_TRUE(JS_IsTypedArrayObject(obj), NS_ERROR_FAILURE);
+    NS_ENSURE_TRUE(JS_IsUint8Array(obj), NS_ERROR_FAILURE);
+    uint32_t nbytes = JS_GetTypedArrayByteLength(obj);
+    uint8_t* data = JS_GetUint8ArrayData(obj);
     if (!data) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
     FallibleTArray<uint8_t> fallibleArr;
     if (!fallibleArr.InsertElementsAt(0, data, nbytes)) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
     InfallibleTArray<uint8_t> arr;
--- a/dom/network/src/TCPSocketParent.cpp
+++ b/dom/network/src/TCPSocketParent.cpp
@@ -151,20 +151,20 @@ TCPSocketParent::SendCallback(const nsAS
     }
     data = str;
 
   } else if (aDataVal.isUndefined() || aDataVal.isNull()) {
     data = mozilla::void_t();
 
   } else if (aDataVal.isObject()) {
     JSObject* obj = &aDataVal.toObject();
-    if (JS_IsTypedArrayObject(obj, aCx)) {
-      NS_ENSURE_TRUE(JS_IsUint8Array(obj, aCx), NS_ERROR_FAILURE);
-      uint32_t nbytes = JS_GetTypedArrayByteLength(obj, aCx);
-      uint8_t* buffer = JS_GetUint8ArrayData(obj, aCx);
+    if (JS_IsTypedArrayObject(obj)) {
+      NS_ENSURE_TRUE(JS_IsUint8Array(obj), NS_ERROR_FAILURE);
+      uint32_t nbytes = JS_GetTypedArrayByteLength(obj);
+      uint8_t* buffer = JS_GetUint8ArrayData(obj);
       if (!buffer) {
         FireInteralError(this, __LINE__);
         return NS_ERROR_OUT_OF_MEMORY;
       }
       FallibleTArray<uint8_t> fallibleArr;
       if (!fallibleArr.InsertElementsAt(0, buffer, nbytes)) {
         FireInteralError(this, __LINE__);
         return NS_ERROR_OUT_OF_MEMORY;
--- a/dom/plugins/base/nsJSNPRuntime.cpp
+++ b/dom/plugins/base/nsJSNPRuntime.cpp
@@ -455,30 +455,22 @@ JSValToNPVariant(NPP npp, JSContext *cx,
 
     return true;
   }
 
   // The reflected plugin object may be in another compartment if the plugin
   // element has since been adopted into a new document. We don't bother
   // transplanting the plugin objects, and just do a unwrap with security
   // checks if we encounter one of them as an argument. If the unwrap fails,
-  // we clear the pending exception and just run with the original wrapped object,
-  // since sometimes there are legitimate cases where a security wrapper ends
-  // up here (for example, Location objects, which are _always_ behind security
-  // wrappers).
-  //
-  // NB: In addition to clearing the pending exception, we also have to temporarily
-  // disable the error reporter, because SpiderMonkey calls it directly if there's
-  // no JS code on the stack, which might be the case here.
+  // we run with the original wrapped object, since sometimes there are
+  // legitimate cases where a security wrapper ends up here (for example,
+  // Location objects, which are _always_ behind security wrappers).
   JSObject *obj = JSVAL_TO_OBJECT(val);
-  JSErrorReporter reporter = JS_SetErrorReporter(cx, NULL);
-  obj = js::UnwrapObjectChecked(cx, obj);
-  JS_SetErrorReporter(cx, reporter);
+  obj = js::UnwrapObjectChecked(obj);
   if (!obj) {
-    JS_ClearPendingException(cx);
     obj = JSVAL_TO_OBJECT(val);
   }
 
   NPObject *npobj = nsJSObjWrapper::GetNewOrUsed(npp, cx, obj);
   if (!npobj) {
     return false;
   }
 
@@ -1129,17 +1121,17 @@ nsJSObjWrapper::GetNewOrUsed(NPP npp, JS
 // wrapper.
 //
 // Because this function unwraps, its return value must be wrapped for the cx
 // compartment for callers that plan to hold onto the result or do anything
 // substantial with it.
 static JSObject *
 GetNPObjectWrapper(JSContext *cx, JSObject *obj, bool wrapResult = true)
 {
-  while (obj && (obj = js::UnwrapObjectChecked(cx, obj))) {
+  while (obj && (obj = js::UnwrapObjectChecked(obj))) {
     if (JS_GetClass(obj) == &sNPObjectJSWrapperClass) {
       if (wrapResult && !JS_WrapObject(cx, &obj)) {
         return NULL;
       }
       return obj;
     }
     if (!::JS_GetPrototype(cx, obj, &obj)) {
       return NULL;
--- a/dom/system/gonk/SystemWorkerManager.cpp
+++ b/dom/system/gonk/SystemWorkerManager.cpp
@@ -84,31 +84,31 @@ PostToRIL(JSContext *cx, unsigned argc, 
     if (!abs.encode(cx, str)) {
       return false;
     }
 
     size = JS_GetStringLength(str);
     data = abs.ptr();
   } else if (!JSVAL_IS_PRIMITIVE(v)) {
     JSObject *obj = JSVAL_TO_OBJECT(v);
-    if (!JS_IsTypedArrayObject(obj, cx)) {
+    if (!JS_IsTypedArrayObject(obj)) {
       JS_ReportError(cx, "Object passed in wasn't a typed array");
       return false;
     }
 
-    uint32_t type = JS_GetTypedArrayType(obj, cx);
+    uint32_t type = JS_GetTypedArrayType(obj);
     if (type != js::ArrayBufferView::TYPE_INT8 &&
         type != js::ArrayBufferView::TYPE_UINT8 &&
         type != js::ArrayBufferView::TYPE_UINT8_CLAMPED) {
       JS_ReportError(cx, "Typed array data is not octets");
       return false;
     }
 
-    size = JS_GetTypedArrayByteLength(obj, cx);
-    data = JS_GetArrayBufferViewData(obj, cx);
+    size = JS_GetTypedArrayByteLength(obj);
+    data = JS_GetArrayBufferViewData(obj);
   } else {
     JS_ReportError(cx,
                    "Incorrect argument. Expecting a string or a typed array");
     return false;
   }
 
   if (size > RilRawData::MAX_DATA_SIZE) {
     JS_ReportError(cx, "Passed-in data is too large");
@@ -170,17 +170,17 @@ RILReceiver::DispatchRILEvent::RunTask(J
 {
   JSObject *obj = JS_GetGlobalObject(aCx);
 
   JSObject *array = JS_NewUint8Array(aCx, mMessage->mSize);
   if (!array) {
     return false;
   }
 
-  memcpy(JS_GetArrayBufferViewData(array, aCx), mMessage->mData, mMessage->mSize);
+  memcpy(JS_GetArrayBufferViewData(array), mMessage->mData, mMessage->mSize);
   jsval argv[] = { OBJECT_TO_JSVAL(array) };
   return JS_CallFunctionName(aCx, obj, "onRILMessage", NS_ARRAY_LENGTH(argv),
                              argv, argv);
 }
 
 #ifdef MOZ_WIDGET_GONK
 
 JSBool
@@ -212,36 +212,36 @@ DoNetdCommand(JSContext *cx, unsigned ar
 
     data = abs.ptr();
     if (!data) {
       JS_ReportError(cx, "Command string is empty");
       return false;
     }
   } else if (!JSVAL_IS_PRIMITIVE(v)) {
     JSObject *obj = JSVAL_TO_OBJECT(v);
-    if (!JS_IsTypedArrayObject(obj, cx)) {
+    if (!JS_IsTypedArrayObject(obj)) {
       JS_ReportError(cx, "Object passed in wasn't a typed array");
       return false;
     }
 
-    uint32_t type = JS_GetTypedArrayType(obj, cx);
+    uint32_t type = JS_GetTypedArrayType(obj);
     if (type != js::ArrayBufferView::TYPE_INT8 &&
         type != js::ArrayBufferView::TYPE_UINT8 &&
         type != js::ArrayBufferView::TYPE_UINT8_CLAMPED) {
       JS_ReportError(cx, "Typed array data is not octets");
       return false;
     }
 
-    size = JS_GetTypedArrayByteLength(obj, cx);
+    size = JS_GetTypedArrayByteLength(obj);
     if (!size) {
       JS_ReportError(cx, "Typed array byte length is zero");
       return false;
     }
 
-    data = JS_GetArrayBufferViewData(obj, cx);
+    data = JS_GetArrayBufferViewData(obj);
     if (!data) {
       JS_ReportError(cx, "Array buffer view data is NULL");
       return false;
     }
   } else {
     JS_ReportError(cx,
                    "Incorrect argument. Expecting a string or a typed array");
     return false;
@@ -317,17 +317,17 @@ NetdReceiver::DispatchNetdEvent::RunTask
 {
   JSObject *obj = JS_GetGlobalObject(aCx);
 
   JSObject *array = JS_NewUint8Array(aCx, mMessage->mSize);
   if (!array) {
     return false;
   }
 
-  memcpy(JS_GetUint8ArrayData(array, aCx), mMessage->mData, mMessage->mSize);
+  memcpy(JS_GetUint8ArrayData(array), mMessage->mData, mMessage->mSize);
   jsval argv[] = { OBJECT_TO_JSVAL(array) };
   return JS_CallFunctionName(aCx, obj, "onNetdMessage", NS_ARRAY_LENGTH(argv),
                              argv, argv);
 }
 
 #endif // MOZ_WIDGET_GONK
 
 } // anonymous namespace
--- a/dom/workers/FileReaderSync.cpp
+++ b/dom/workers/FileReaderSync.cpp
@@ -90,18 +90,18 @@ FileReaderSync::ReadAsArrayBuffer(JSCont
   JSObject* jsArrayBuffer = JS_NewArrayBuffer(aCx, blobSize);
   if (!jsArrayBuffer) {
     // XXXkhuey we need a way to indicate to the bindings that the call failed
     // but there's already a pending exception that we should not clobber.
     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
     return nullptr;
   }
 
-  uint32_t bufferLength = JS_GetArrayBufferByteLength(jsArrayBuffer, aCx);
-  uint8_t* arrayBuffer = JS_GetArrayBufferData(jsArrayBuffer, aCx);
+  uint32_t bufferLength = JS_GetArrayBufferByteLength(jsArrayBuffer);
+  uint8_t* arrayBuffer = JS_GetArrayBufferData(jsArrayBuffer);
 
   nsCOMPtr<nsIInputStream> stream;
   rv = blob->GetInternalStream(getter_AddRefs(stream));
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
--- a/dom/workers/ImageData.cpp
+++ b/dom/workers/ImageData.cpp
@@ -35,18 +35,18 @@ public:
     return JS_InitClass(aCx, aObj, NULL, &sClass, Construct, 0, sProperties,
                         NULL, NULL, NULL);
   }
 
   static JSObject*
   Create(JSContext* aCx, uint32_t aWidth, uint32_t aHeight, JSObject *aData)
   {
     MOZ_ASSERT(aData);
-    MOZ_ASSERT(JS_IsTypedArrayObject(aData, aCx));
-    MOZ_ASSERT(JS_IsUint8ClampedArray(aData, aCx));
+    MOZ_ASSERT(JS_IsTypedArrayObject(aData));
+    MOZ_ASSERT(JS_IsUint8ClampedArray(aData));
 
     JSObject* obj = JS_NewObject(aCx, &sClass, NULL, NULL);
     if (!obj) {
       return NULL;
     }
 
     JS_SetReservedSlot(obj, SLOT_width, UINT_TO_JSVAL(aWidth));
     JS_SetReservedSlot(obj, SLOT_height, UINT_TO_JSVAL(aHeight));
--- a/dom/workers/XMLHttpRequest.cpp
+++ b/dom/workers/XMLHttpRequest.cpp
@@ -2003,17 +2003,17 @@ XMLHttpRequest::Send(JSObject* aBody, Er
   if (!mProxy) {
     aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     return;
   }
 
   JSContext* cx = GetJSContext();
 
   jsval valToClone;
-  if (JS_IsArrayBufferObject(aBody, cx) || file::GetDOMBlobFromJSObject(aBody)) {
+  if (JS_IsArrayBufferObject(aBody) || file::GetDOMBlobFromJSObject(aBody)) {
     valToClone = OBJECT_TO_JSVAL(aBody);
   }
   else {
     JSString* bodyStr = JS_ValueToString(cx, OBJECT_TO_JSVAL(aBody));
     if (!bodyStr) {
       aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
       return;
     }
--- a/js/src/ctypes/CTypes.cpp
+++ b/js/src/ctypes/CTypes.cpp
@@ -2111,17 +2111,17 @@ ConvertToJS(JSContext* cx,
 // ambiguity to a C type. Elements of a Int8Array are converted to
 // ctypes.int8_t, UInt8Array to ctypes.uint8_t, etc.
 bool CanConvertTypedArrayItemTo(JSObject *baseType, JSObject *valObj, JSContext *cx) {
   TypeCode baseTypeCode = CType::GetTypeCode(baseType);
   if (baseTypeCode == TYPE_void_t) {
     return true;
   }
   TypeCode elementTypeCode;
-  switch (JS_GetTypedArrayType(valObj, cx)) {
+  switch (JS_GetTypedArrayType(valObj)) {
   case TypedArray::TYPE_INT8:
     elementTypeCode = TYPE_int8_t;
     break;
   case TypedArray::TYPE_UINT8:
   case TypedArray::TYPE_UINT8_CLAMPED:
     elementTypeCode = TYPE_uint8_t;
     break;
   case TypedArray::TYPE_INT16:
@@ -2336,31 +2336,31 @@ ImplicitConvert(JSContext* cx,
         memcpy(*jscharBuffer, sourceChars, sourceLength * sizeof(jschar));
         (*jscharBuffer)[sourceLength] = 0;
         break;
       }
       default:
         return TypeError(cx, "string pointer", val);
       }
       break;
-    } else if (!JSVAL_IS_PRIMITIVE(val) && JS_IsArrayBufferObject(valObj, cx)) {
+    } else if (!JSVAL_IS_PRIMITIVE(val) && JS_IsArrayBufferObject(valObj)) {
       // Convert ArrayBuffer to pointer without any copy.
       // Just as with C arrays, we make no effort to
       // keep the ArrayBuffer alive.
-      *static_cast<void**>(buffer) = JS_GetArrayBufferData(valObj, cx);
+      *static_cast<void**>(buffer) = JS_GetArrayBufferData(valObj);
       break;
-    } if (!JSVAL_IS_PRIMITIVE(val) && JS_IsTypedArrayObject(valObj, cx)) {
+    } if (!JSVAL_IS_PRIMITIVE(val) && JS_IsTypedArrayObject(valObj)) {
       if(!CanConvertTypedArrayItemTo(baseType, valObj, cx)) {
         return TypeError(cx, "typed array with the appropriate type", val);
       }
 
       // Convert TypedArray to pointer without any copy.
       // Just as with C arrays, we make no effort to
       // keep the TypedArray alive.
-      *static_cast<void**>(buffer) = JS_GetArrayBufferViewData(valObj, cx);
+      *static_cast<void**>(buffer) = JS_GetArrayBufferViewData(valObj);
       break;
     }
     return TypeError(cx, "pointer", val);
   }
   case TYPE_array: {
     JSObject* baseType = ArrayType::GetBaseType(targetType);
     size_t targetLength = ArrayType::GetLength(targetType);
 
@@ -2439,44 +2439,44 @@ ImplicitConvert(JSContext* cx,
         char* data = intermediate.get() + elementSize * i;
         if (!ImplicitConvert(cx, item.jsval_value(), baseType, data, false, NULL))
           return false;
       }
 
       memcpy(buffer, intermediate.get(), arraySize);
 
     } else if (!JSVAL_IS_PRIMITIVE(val) &&
-               JS_IsArrayBufferObject(valObj, cx)) {
+               JS_IsArrayBufferObject(valObj)) {
       // Check that array is consistent with type, then
       // copy the array.
-      uint32_t sourceLength = JS_GetArrayBufferByteLength(valObj, cx);
+      uint32_t sourceLength = JS_GetArrayBufferByteLength(valObj);
       size_t elementSize = CType::GetSize(baseType);
       size_t arraySize = elementSize * targetLength;
       if (arraySize != size_t(sourceLength)) {
         JS_ReportError(cx, "ArrayType length does not match source ArrayBuffer length");
         return false;
       }
-      memcpy(buffer, JS_GetArrayBufferData(valObj, cx), sourceLength);
+      memcpy(buffer, JS_GetArrayBufferData(valObj), sourceLength);
       break;
     }  else if (!JSVAL_IS_PRIMITIVE(val) &&
-               JS_IsTypedArrayObject(valObj, cx)) {
+               JS_IsTypedArrayObject(valObj)) {
       // Check that array is consistent with type, then
       // copy the array.
       if(!CanConvertTypedArrayItemTo(baseType, valObj, cx)) {
         return TypeError(cx, "typed array with the appropriate type", val);
       }
 
-      uint32_t sourceLength = JS_GetTypedArrayByteLength(valObj, cx);
+      uint32_t sourceLength = JS_GetTypedArrayByteLength(valObj);
       size_t elementSize = CType::GetSize(baseType);
       size_t arraySize = elementSize * targetLength;
       if (arraySize != size_t(sourceLength)) {
         JS_ReportError(cx, "typed array length does not match source TypedArray length");
         return false;
       }
-      memcpy(buffer, JS_GetArrayBufferViewData(valObj, cx), sourceLength);
+      memcpy(buffer, JS_GetArrayBufferViewData(valObj), sourceLength);
       break;
     } else {
       // Don't implicitly convert to string. Users can implicitly convert
       // with `String(x)` or `""+x`.
       return TypeError(cx, "array", val);
     }
     break;
   }
--- a/js/src/jsapi-tests/testArrayBuffer.cpp
+++ b/js/src/jsapi-tests/testArrayBuffer.cpp
@@ -31,61 +31,61 @@ BEGIN_TEST(testArrayBuffer_bug720949_ste
 
     for (unsigned i = 0; i < NUM_TEST_BUFFERS; i++) {
         JS::HandleObject obj = testBuf[i];
         JS::HandleObject view = testArray[i];
         uint32_t size = sizes[i];
         jsval v;
 
         // Byte lengths should all agree
-        CHECK(JS_IsArrayBufferObject(obj, cx));
-        CHECK_EQUAL(JS_GetArrayBufferByteLength(obj, cx), size);
+        CHECK(JS_IsArrayBufferObject(obj));
+        CHECK_EQUAL(JS_GetArrayBufferByteLength(obj), size);
         JS_GetProperty(cx, obj, "byteLength", &v);
         CHECK_SAME(v, INT_TO_JSVAL(size));
         JS_GetProperty(cx, view, "byteLength", &v);
         CHECK_SAME(v, INT_TO_JSVAL(size));
 
         // Modifying the underlying data should update the value returned through the view
-        uint8_t *data = JS_GetArrayBufferData(obj, cx);
+        uint8_t *data = JS_GetArrayBufferData(obj);
         CHECK(data != NULL);
         *reinterpret_cast<uint32_t*>(data) = MAGIC_VALUE_2;
         CHECK(JS_GetElement(cx, view, 0, &v));
         CHECK_SAME(v, INT_TO_JSVAL(MAGIC_VALUE_2));
 
         // Steal the contents
         void *contents;
         CHECK(JS_StealArrayBufferContents(cx, obj, &contents, &data));
         CHECK(contents != NULL);
         CHECK(data != NULL);
 
         // Check that the original ArrayBuffer is neutered
-        CHECK_EQUAL(JS_GetArrayBufferByteLength(obj, cx), 0);
+        CHECK_EQUAL(JS_GetArrayBufferByteLength(obj), 0);
         CHECK(JS_GetProperty(cx, obj, "byteLength", &v));
         CHECK_SAME(v, INT_TO_JSVAL(0));
         CHECK(JS_GetProperty(cx, view, "byteLength", &v));
         CHECK_SAME(v, INT_TO_JSVAL(0));
         CHECK(JS_GetProperty(cx, view, "byteOffset", &v));
         CHECK_SAME(v, INT_TO_JSVAL(0));
         CHECK(JS_GetProperty(cx, view, "length", &v));
         CHECK_SAME(v, INT_TO_JSVAL(0));
-        CHECK_EQUAL(JS_GetArrayBufferByteLength(obj, cx), 0);
+        CHECK_EQUAL(JS_GetArrayBufferByteLength(obj), 0);
         v = JSVAL_VOID;
         JS_GetElement(cx, obj, 0, &v);
         CHECK_SAME(v, JSVAL_VOID);
 
         // Transfer to a new ArrayBuffer
         js::RootedObject dst(cx, JS_NewArrayBufferWithContents(cx, contents));
-        CHECK(JS_IsArrayBufferObject(dst, cx));
-        data = JS_GetArrayBufferData(obj, cx);
+        CHECK(JS_IsArrayBufferObject(dst));
+        data = JS_GetArrayBufferData(obj);
 
         js::RootedObject dstview(cx, JS_NewInt32ArrayWithBuffer(cx, dst, 0, -1));
         CHECK(dstview != NULL);
 
-        CHECK_EQUAL(JS_GetArrayBufferByteLength(dst, cx), size);
-        data = JS_GetArrayBufferData(dst, cx);
+        CHECK_EQUAL(JS_GetArrayBufferByteLength(dst), size);
+        data = JS_GetArrayBufferData(dst);
         CHECK(data != NULL);
         CHECK_EQUAL(*reinterpret_cast<uint32_t*>(data), MAGIC_VALUE_2);
         CHECK(JS_GetElement(cx, dstview, 0, &v));
         CHECK_SAME(v, INT_TO_JSVAL(MAGIC_VALUE_2));
     }
 
     return true;
 }
--- a/js/src/jsapi-tests/testTypedArrays.cpp
+++ b/js/src/jsapi-tests/testTypedArrays.cpp
@@ -23,26 +23,26 @@ BEGIN_TEST(testTypedArrays)
         TestPlainTypedArray<JS_NewUint16Array, uint16_t, JS_GetUint16ArrayData>(cx) &&
         TestPlainTypedArray<JS_NewInt32Array, int32_t, JS_GetInt32ArrayData>(cx) &&
         TestPlainTypedArray<JS_NewUint32Array, uint32_t, JS_GetUint32ArrayData>(cx) &&
         TestPlainTypedArray<JS_NewFloat32Array, float, JS_GetFloat32ArrayData>(cx) &&
         TestPlainTypedArray<JS_NewFloat64Array, double, JS_GetFloat64ArrayData>(cx);
 
     size_t nbytes = sizeof(double) * 8;
     RootedObject buffer(cx, JS_NewArrayBuffer(cx, nbytes));
-    CHECK(JS_IsArrayBufferObject(buffer, cx));
+    CHECK(JS_IsArrayBufferObject(buffer));
 
     RootedObject proto(cx);
     JS_GetPrototype(cx, buffer, proto.address());
-    CHECK(!JS_IsArrayBufferObject(proto, cx));
+    CHECK(!JS_IsArrayBufferObject(proto));
     RootedObject dummy(cx, JS_GetParent(proto));
-    CHECK(!JS_IsArrayBufferObject(dummy, cx));
+    CHECK(!JS_IsArrayBufferObject(dummy));
 
-    CHECK_EQUAL(JS_GetArrayBufferByteLength(buffer, cx), nbytes);
-    memset(JS_GetArrayBufferData(buffer, cx), 1, nbytes);
+    CHECK_EQUAL(JS_GetArrayBufferByteLength(buffer), nbytes);
+    memset(JS_GetArrayBufferData(buffer), 1, nbytes);
 
     ok = ok &&
         TestArrayFromBuffer<JS_NewInt8ArrayWithBuffer, JS_NewInt8ArrayFromArray, int8_t, JS_GetInt8ArrayData>(cx) &&
         TestArrayFromBuffer<JS_NewUint8ArrayWithBuffer, JS_NewUint8ArrayFromArray, uint8_t, JS_GetUint8ArrayData>(cx) &&
         TestArrayFromBuffer<JS_NewUint8ClampedArrayWithBuffer, JS_NewUint8ClampedArrayFromArray, uint8_t, JS_GetUint8ClampedArrayData>(cx) &&
         TestArrayFromBuffer<JS_NewInt16ArrayWithBuffer, JS_NewInt16ArrayFromArray, int16_t, JS_GetInt16ArrayData>(cx) &&
         TestArrayFromBuffer<JS_NewUint16ArrayWithBuffer, JS_NewUint16ArrayFromArray, uint16_t, JS_GetUint16ArrayData>(cx) &&
         TestArrayFromBuffer<JS_NewInt32ArrayWithBuffer, JS_NewInt32ArrayFromArray, int32_t, JS_GetInt32ArrayData>(cx) &&
@@ -50,79 +50,79 @@ BEGIN_TEST(testTypedArrays)
         TestArrayFromBuffer<JS_NewFloat32ArrayWithBuffer, JS_NewFloat32ArrayFromArray, float, JS_GetFloat32ArrayData>(cx) &&
         TestArrayFromBuffer<JS_NewFloat64ArrayWithBuffer, JS_NewFloat64ArrayFromArray, double, JS_GetFloat64ArrayData>(cx);
 
     return ok;
 }
 
 template<JSObject *Create(JSContext *, uint32_t),
          typename Element,
-         Element *GetData(JSObject *, JSContext *)>
+         Element *GetData(JSObject *)>
 bool
 TestPlainTypedArray(JSContext *cx)
 {
     RootedObject array(cx, Create(cx, 7));
-    CHECK(JS_IsTypedArrayObject(array, cx));
+    CHECK(JS_IsTypedArrayObject(array));
     RootedObject proto(cx);
     JS_GetPrototype(cx, array, proto.address());
-    CHECK(!JS_IsTypedArrayObject(proto, cx));
+    CHECK(!JS_IsTypedArrayObject(proto));
     RootedObject dummy(cx, JS_GetParent(proto));
-    CHECK(!JS_IsTypedArrayObject(dummy, cx));
+    CHECK(!JS_IsTypedArrayObject(dummy));
 
-    CHECK_EQUAL(JS_GetTypedArrayLength(array, cx), 7);
-    CHECK_EQUAL(JS_GetTypedArrayByteOffset(array, cx), 0);
-    CHECK_EQUAL(JS_GetTypedArrayByteLength(array, cx), sizeof(Element) * 7);
+    CHECK_EQUAL(JS_GetTypedArrayLength(array), 7);
+    CHECK_EQUAL(JS_GetTypedArrayByteOffset(array), 0);
+    CHECK_EQUAL(JS_GetTypedArrayByteLength(array), sizeof(Element) * 7);
 
     Element *data;
-    CHECK(data = GetData(array, cx));
+    CHECK(data = GetData(array));
     *data = 13;
     jsval v;
     CHECK(JS_GetElement(cx, array, 0, &v));
     CHECK_SAME(v, INT_TO_JSVAL(13));
 
     return true;
 }
 
 template<JSObject *CreateWithBuffer(JSContext *, JSObject *, uint32_t, int32_t),
          JSObject *CreateFromArray(JSContext *, JSObject *),
          typename Element,
-         Element *GetData(JSObject *, JSContext *)>
+         Element *GetData(JSObject *)>
 bool
 TestArrayFromBuffer(JSContext *cx)
 {
     size_t elts = 8;
     size_t nbytes = elts * sizeof(Element);
     RootedObject buffer(cx, JS_NewArrayBuffer(cx, nbytes));
     uint8_t *bufdata;
-    CHECK(bufdata = JS_GetArrayBufferData(buffer, cx));
+    CHECK(bufdata = JS_GetArrayBufferData(buffer));
     memset(bufdata, 1, nbytes);
 
     RootedObject array(cx, CreateWithBuffer(cx, buffer, 0, -1));
-    CHECK_EQUAL(JS_GetTypedArrayLength(array, cx), elts);
-    CHECK_EQUAL(JS_GetTypedArrayByteOffset(array, cx), 0);
-    CHECK_EQUAL(JS_GetTypedArrayByteLength(array, cx), nbytes);
-    CHECK_EQUAL(JS_GetArrayBufferViewBuffer(array, cx), (JSObject*) buffer);
+    CHECK_EQUAL(JS_GetTypedArrayLength(array), elts);
+    CHECK_EQUAL(JS_GetTypedArrayByteOffset(array), 0);
+    CHECK_EQUAL(JS_GetTypedArrayByteLength(array), nbytes);
+    CHECK_EQUAL(JS_GetArrayBufferViewBuffer(array), (JSObject*) buffer);
 
     Element *data;
-    CHECK(data = GetData(array, cx));
-    CHECK(bufdata = JS_GetArrayBufferData(buffer, cx));
+    CHECK(data = GetData(array));
+    CHECK(bufdata = JS_GetArrayBufferData(buffer));
     CHECK_EQUAL((void*) data, (void*) bufdata);
 
     CHECK_EQUAL(*bufdata, 1);
     CHECK_EQUAL(*reinterpret_cast<uint8_t*>(data), 1);
 
     RootedObject shortArray(cx, CreateWithBuffer(cx, buffer, 0, elts / 2));
-    CHECK_EQUAL(JS_GetTypedArrayLength(shortArray, cx), elts / 2);
-    CHECK_EQUAL(JS_GetTypedArrayByteOffset(shortArray, cx), 0);
-    CHECK_EQUAL(JS_GetTypedArrayByteLength(shortArray, cx), nbytes / 2);
+    CHECK_EQUAL(JS_GetTypedArrayLength(shortArray), elts / 2);
+    CHECK_EQUAL(JS_GetTypedArrayByteOffset(shortArray), 0);
+    CHECK_EQUAL(JS_GetTypedArrayByteLength(shortArray), nbytes / 2);
 
     RootedObject ofsArray(cx, CreateWithBuffer(cx, buffer, nbytes / 2, -1));
-    CHECK_EQUAL(JS_GetTypedArrayLength(ofsArray, cx), elts / 2);
-    CHECK_EQUAL(JS_GetTypedArrayByteOffset(ofsArray, cx), nbytes / 2);
-    CHECK_EQUAL(JS_GetTypedArrayByteLength(ofsArray, cx), nbytes / 2);
+    CHECK_EQUAL(JS_GetTypedArrayLength(ofsArray), elts / 2);
+    CHECK_EQUAL(JS_GetTypedArrayByteOffset(ofsArray), nbytes / 2);
+    CHECK_EQUAL(JS_GetTypedArrayByteLength(ofsArray), nbytes / 2);
 
     // Make sure all 3 views reflect the same buffer at the expected locations
     jsval v = INT_TO_JSVAL(39);
     JS_SetElement(cx, array, 0, &v);
     jsval v2;
     CHECK(JS_GetElement(cx, array, 0, &v2));
     CHECK_SAME(v, v2);
     CHECK(JS_GetElement(cx, shortArray, 0, &v2));
--- a/js/src/jsclone.cpp
+++ b/js/src/jsclone.cpp
@@ -562,23 +562,23 @@ JSStructuredCloneWriter::checkStack()
 }
 
 JS_PUBLIC_API(JSBool)
 JS_WriteTypedArray(JSStructuredCloneWriter *w, jsval v)
 {
     JS_ASSERT(v.isObject());
     RootedObject obj(w->context(), &v.toObject());
 
-    // If the object is a security wrapper, try puncturing it. This may throw
-    // if the access is not allowed.
-    if (obj->isWrapper()) {
-        JSObject *unwrapped = UnwrapObjectChecked(w->context(), obj);
-        if (!unwrapped)
-            return false;
-        obj = unwrapped;
+    // If the object is a security wrapper, see if we're allowed to unwrap it.
+    // If we aren't, throw.
+    if (obj->isWrapper())
+        obj = UnwrapObjectChecked(obj);
+    if (!obj) {
+        JS_ReportError(w->context(), "Permission denied to access object");
+        return false;
     }
     return w->writeTypedArray(obj);
 }
 
 bool
 JSStructuredCloneWriter::writeTypedArray(HandleObject arr)
 {
     if (!out.writePair(ArrayTypeToTag(TypedArray::type(arr)), TypedArray::length(arr)))
@@ -669,19 +669,21 @@ JSStructuredCloneWriter::startWrite(cons
         return out.writePair(SCTAG_NULL, 0);
     } else if (v.isUndefined()) {
         return out.writePair(SCTAG_UNDEFINED, 0);
     } else if (v.isObject()) {
         RootedObject obj(context(), &v.toObject());
 
         // The object might be a security wrapper. See if we can clone what's
         // behind it. If we can, unwrap the object.
-        obj = UnwrapObjectChecked(context(), obj);
-        if (!obj)
+        obj = UnwrapObjectChecked(obj);
+        if (!obj) {
+            JS_ReportError(context(), "Permission denied to access object");
             return false;
+        }
 
         AutoCompartment ac(context(), obj);
 
         bool backref;
         if (!startObject(obj, &backref))
             return false;
         if (backref)
             return true;
@@ -892,33 +894,33 @@ JSStructuredCloneReader::readTypedArray(
 
     if (!obj)
         return false;
     vp->setObject(*obj);
 
     JS_ASSERT(TypedArray::length(obj) == nelems);
     switch (tag) {
       case SCTAG_TYPED_ARRAY_INT8:
-        return in.readArray((uint8_t*) JS_GetInt8ArrayData(obj, context()), nelems);
+        return in.readArray((uint8_t*) JS_GetInt8ArrayData(obj), nelems);
       case SCTAG_TYPED_ARRAY_UINT8:
-        return in.readArray(JS_GetUint8ArrayData(obj, context()), nelems);
+        return in.readArray(JS_GetUint8ArrayData(obj), nelems);
       case SCTAG_TYPED_ARRAY_INT16:
-        return in.readArray((uint16_t*) JS_GetInt16ArrayData(obj, context()), nelems);
+        return in.readArray((uint16_t*) JS_GetInt16ArrayData(obj), nelems);
       case SCTAG_TYPED_ARRAY_UINT16:
-        return in.readArray(JS_GetUint16ArrayData(obj, context()), nelems);
+        return in.readArray(JS_GetUint16ArrayData(obj), nelems);
       case SCTAG_TYPED_ARRAY_INT32:
-        return in.readArray((uint32_t*) JS_GetInt32ArrayData(obj, context()), nelems);
+        return in.readArray((uint32_t*) JS_GetInt32ArrayData(obj), nelems);
       case SCTAG_TYPED_ARRAY_UINT32:
-        return in.readArray(JS_GetUint32ArrayData(obj, context()), nelems);
+        return in.readArray(JS_GetUint32ArrayData(obj), nelems);
       case SCTAG_TYPED_ARRAY_FLOAT32:
-        return in.readArray((uint32_t*) JS_GetFloat32ArrayData(obj, context()), nelems);
+        return in.readArray((uint32_t*) JS_GetFloat32ArrayData(obj), nelems);
       case SCTAG_TYPED_ARRAY_FLOAT64:
-        return in.readArray((uint64_t*) JS_GetFloat64ArrayData(obj, context()), nelems);
+        return in.readArray((uint64_t*) JS_GetFloat64ArrayData(obj), nelems);
       case SCTAG_TYPED_ARRAY_UINT8_CLAMPED:
-        return in.readArray(JS_GetUint8ClampedArrayData(obj, context()), nelems);
+        return in.readArray(JS_GetUint8ClampedArrayData(obj), nelems);
       default:
         JS_NOT_REACHED("unknown TypedArray type");
         return false;
     }
 }
 
 bool
 JSStructuredCloneReader::readArrayBuffer(uint32_t nbytes, Value *vp)
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -1178,258 +1178,247 @@ JS_NewArrayBuffer(JSContext *cx, uint32_
 
 /*
  * Check whether obj supports JS_GetTypedArray* APIs. Note that this may return
  * false if a security wrapper is encountered that denies the unwrapping. If
  * this test or one of the JS_Is*Array tests succeeds, then it is safe to call
  * the various accessor JSAPI calls defined below.
  */
 extern JS_FRIEND_API(JSBool)
-JS_IsTypedArrayObject(JSObject *obj, JSContext *cx);
+JS_IsTypedArrayObject(JSObject *obj);
 
 /*
  * Check whether obj supports JS_GetArrayBufferView* APIs. Note that this may
  * return false if a security wrapper is encountered that denies the
  * unwrapping. If this test or one of the more specific tests succeeds, then it
  * is safe to call the various ArrayBufferView accessor JSAPI calls defined
- * below. cx MUST be non-NULL and valid.
+ * below.
  */
 extern JS_FRIEND_API(JSBool)
-JS_IsArrayBufferViewObject(JSObject *obj, JSContext *cx);
+JS_IsArrayBufferViewObject(JSObject *obj);
 
 /*
  * Test for specific typed array types (ArrayBufferView subtypes)
  */
 
 extern JS_FRIEND_API(JSBool)
-JS_IsInt8Array(JSObject *obj, JSContext *cx);
+JS_IsInt8Array(JSObject *obj);
 extern JS_FRIEND_API(JSBool)
-JS_IsUint8Array(JSObject *obj, JSContext *cx);
+JS_IsUint8Array(JSObject *obj);
 extern JS_FRIEND_API(JSBool)
-JS_IsUint8ClampedArray(JSObject *obj, JSContext *cx);
+JS_IsUint8ClampedArray(JSObject *obj);
 extern JS_FRIEND_API(JSBool)
-JS_IsInt16Array(JSObject *obj, JSContext *cx);
+JS_IsInt16Array(JSObject *obj);
 extern JS_FRIEND_API(JSBool)
-JS_IsUint16Array(JSObject *obj, JSContext *cx);
+JS_IsUint16Array(JSObject *obj);
 extern JS_FRIEND_API(JSBool)
-JS_IsInt32Array(JSObject *obj, JSContext *cx);
+JS_IsInt32Array(JSObject *obj);
 extern JS_FRIEND_API(JSBool)
-JS_IsUint32Array(JSObject *obj, JSContext *cx);
+JS_IsUint32Array(JSObject *obj);
 extern JS_FRIEND_API(JSBool)
-JS_IsFloat32Array(JSObject *obj, JSContext *cx);
+JS_IsFloat32Array(JSObject *obj);
 extern JS_FRIEND_API(JSBool)
-JS_IsFloat64Array(JSObject *obj, JSContext *cx);
-
+JS_IsFloat64Array(JSObject *obj);
 
 /*
  * Unwrap Typed arrays all at once. Return NULL without throwing if the object
  * cannot be viewed as the correct typed array, or the typed array object on
  * success, filling both outparameters.
  */
 extern JS_FRIEND_API(JSObject *)
-JS_GetObjectAsInt8Array(JSContext *cx, JSObject *obj, uint32_t *length, int8_t **data);
+JS_GetObjectAsInt8Array(JSObject *obj, uint32_t *length, int8_t **data);
 extern JS_FRIEND_API(JSObject *)
-JS_GetObjectAsUint8Array(JSContext *cx, JSObject *obj, uint32_t *length, uint8_t **data);
+JS_GetObjectAsUint8Array(JSObject *obj, uint32_t *length, uint8_t **data);
 extern JS_FRIEND_API(JSObject *)
-JS_GetObjectAsUint8ClampedArray(JSContext *cx, JSObject *obj, uint32_t *length, uint8_t **data);
+JS_GetObjectAsUint8ClampedArray(JSObject *obj, uint32_t *length, uint8_t **data);
 extern JS_FRIEND_API(JSObject *)
-JS_GetObjectAsInt16Array(JSContext *cx, JSObject *obj, uint32_t *length, int16_t **data);
+JS_GetObjectAsInt16Array(JSObject *obj, uint32_t *length, int16_t **data);
 extern JS_FRIEND_API(JSObject *)
-JS_GetObjectAsUint16Array(JSContext *cx, JSObject *obj, uint32_t *length, uint16_t **data);
+JS_GetObjectAsUint16Array(JSObject *obj, uint32_t *length, uint16_t **data);
 extern JS_FRIEND_API(JSObject *)
-JS_GetObjectAsInt32Array(JSContext *cx, JSObject *obj, uint32_t *length, int32_t **data);
+JS_GetObjectAsInt32Array(JSObject *obj, uint32_t *length, int32_t **data);
 extern JS_FRIEND_API(JSObject *)
-JS_GetObjectAsUint32Array(JSContext *cx, JSObject *obj, uint32_t *length, uint32_t **data);
+JS_GetObjectAsUint32Array(JSObject *obj, uint32_t *length, uint32_t **data);
 extern JS_FRIEND_API(JSObject *)
-JS_GetObjectAsFloat32Array(JSContext *cx, JSObject *obj, uint32_t *length, float **data);
+JS_GetObjectAsFloat32Array(JSObject *obj, uint32_t *length, float **data);
 extern JS_FRIEND_API(JSObject *)
-JS_GetObjectAsFloat64Array(JSContext *cx, JSObject *obj, uint32_t *length, double **data);
+JS_GetObjectAsFloat64Array(JSObject *obj, uint32_t *length, double **data);
 extern JS_FRIEND_API(JSObject *)
-JS_GetObjectAsArrayBufferView(JSContext *cx, JSObject *obj, uint32_t *length, uint8_t **data);
+JS_GetObjectAsArrayBufferView(JSObject *obj, uint32_t *length, uint8_t **data);
 extern JS_FRIEND_API(JSObject *)
-JS_GetObjectAsArrayBuffer(JSContext *cx, JSObject *obj, uint32_t *length, uint8_t **data);
+JS_GetObjectAsArrayBuffer(JSObject *obj, uint32_t *length, uint8_t **data);
 
 /*
  * Get the type of elements in a typed array.
  *
  * |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow
  * be known that it would pass such a test: it is a typed array or a wrapper of
- * a typed array, and the unwrapping will succeed. If cx is NULL, then DEBUG
- * builds may be unable to assert when unwrapping should be disallowed.
+ * a typed array, and the unwrapping will succeed.
  */
 extern JS_FRIEND_API(JSArrayBufferViewType)
-JS_GetTypedArrayType(JSObject *obj, JSContext *maybecx);
+JS_GetTypedArrayType(JSObject *obj);
 
 /*
  * Check whether obj supports the JS_GetArrayBuffer* APIs. Note that this may
  * return false if a security wrapper is encountered that denies the
  * unwrapping. If this test succeeds, then it is safe to call the various
  * accessor JSAPI calls defined below.
  */
 extern JS_FRIEND_API(JSBool)
-JS_IsArrayBufferObject(JSObject *obj, JSContext *maybecx);
+JS_IsArrayBufferObject(JSObject *obj);
 
 /*
  * Return the available byte length of an array buffer.
  *
  * |obj| must have passed a JS_IsArrayBufferObject test, or somehow be known
  * that it would pass such a test: it is an ArrayBuffer or a wrapper of an
- * ArrayBuffer, and the unwrapping will succeed. If cx is NULL, then DEBUG
- * builds may be unable to assert when unwrapping should be disallowed.
+ * ArrayBuffer, and the unwrapping will succeed.
  */
 extern JS_FRIEND_API(uint32_t)
-JS_GetArrayBufferByteLength(JSObject *obj, JSContext *maybecx);
+JS_GetArrayBufferByteLength(JSObject *obj);
 
 /*
  * Return a pointer to an array buffer's data. The buffer is still owned by the
  * array buffer object, and should not be modified on another thread. The
  * returned pointer is stable across GCs.
  *
  * |obj| must have passed a JS_IsArrayBufferObject test, or somehow be known
  * that it would pass such a test: it is an ArrayBuffer or a wrapper of an
- * ArrayBuffer, and the unwrapping will succeed. If cx is NULL, then DEBUG
- * builds may be unable to assert when unwrapping should be disallowed.
+ * ArrayBuffer, and the unwrapping will succeed.
  */
 extern JS_FRIEND_API(uint8_t *)
-JS_GetArrayBufferData(JSObject *obj, JSContext *maybecx);
+JS_GetArrayBufferData(JSObject *obj);
 
 /*
  * Return the number of elements in a typed array.
  *
  * |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow
  * be known that it would pass such a test: it is a typed array or a wrapper of
- * a typed array, and the unwrapping will succeed. If cx is NULL, then DEBUG
- * builds may be unable to assert when unwrapping should be disallowed.
+ * a typed array, and the unwrapping will succeed.
  */
 extern JS_FRIEND_API(uint32_t)
-JS_GetTypedArrayLength(JSObject *obj, JSContext *cx);
+JS_GetTypedArrayLength(JSObject *obj);
 
 /*
  * Return the byte offset from the start of an array buffer to the start of a
  * typed array view.
  *
  * |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow
  * be known that it would pass such a test: it is a typed array or a wrapper of
- * a typed array, and the unwrapping will succeed. If cx is NULL, then DEBUG
- * builds may be unable to assert when unwrapping should be disallowed.
+ * a typed array, and the unwrapping will succeed.
  */
 extern JS_FRIEND_API(uint32_t)
-JS_GetTypedArrayByteOffset(JSObject *obj, JSContext *cx);
+JS_GetTypedArrayByteOffset(JSObject *obj);
 
 /*
  * Return the byte length of a typed array.
  *
  * |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow
  * be known that it would pass such a test: it is a typed array or a wrapper of
- * a typed array, and the unwrapping will succeed. If cx is NULL, then DEBUG
- * builds may be unable to assert when unwrapping should be disallowed.
+ * a typed array, and the unwrapping will succeed.
  */
 extern JS_FRIEND_API(uint32_t)
-JS_GetTypedArrayByteLength(JSObject *obj, JSContext *cx);
+JS_GetTypedArrayByteLength(JSObject *obj);
 
 /*
  * Check whether obj supports JS_ArrayBufferView* APIs. Note that this may
  * return false if a security wrapper is encountered that denies the
  * unwrapping.
  */
 extern JS_FRIEND_API(JSBool)
-JS_IsArrayBufferViewObject(JSObject *obj, JSContext *cx);
+JS_IsArrayBufferViewObject(JSObject *obj);
 
 /*
  * More generic name for JS_GetTypedArrayByteLength to cover DataViews as well
  */
 extern JS_FRIEND_API(uint32_t)
-JS_GetArrayBufferViewByteLength(JSObject *obj, JSContext *cx);
+JS_GetArrayBufferViewByteLength(JSObject *obj);
 
 /*
  * Return a pointer to the start of the data referenced by a typed array. The
  * data is still owned by the typed array, and should not be modified on
  * another thread.
  *
  * |obj| must have passed a JS_Is*Array test, or somehow be known that it would
  * pass such a test: it is a typed array or a wrapper of a typed array, and the
- * unwrapping will succeed. If cx is NULL, then DEBUG builds may be unable to
- * assert when unwrapping should be disallowed.
+ * unwrapping will succeed.
  */
 
 extern JS_FRIEND_API(int8_t *)
-JS_GetInt8ArrayData(JSObject *obj, JSContext *maybecx);
+JS_GetInt8ArrayData(JSObject *obj);
 extern JS_FRIEND_API(uint8_t *)
-JS_GetUint8ArrayData(JSObject *obj, JSContext *maybecx);
+JS_GetUint8ArrayData(JSObject *obj);
 extern JS_FRIEND_API(uint8_t *)
-JS_GetUint8ClampedArrayData(JSObject *obj, JSContext *maybecx);
+JS_GetUint8ClampedArrayData(JSObject *obj);
 extern JS_FRIEND_API(int16_t *)
-JS_GetInt16ArrayData(JSObject *obj, JSContext *maybecx);
+JS_GetInt16ArrayData(JSObject *obj);
 extern JS_FRIEND_API(uint16_t *)
-JS_GetUint16ArrayData(JSObject *obj, JSContext *maybecx);
+JS_GetUint16ArrayData(JSObject *obj);
 extern JS_FRIEND_API(int32_t *)
-JS_GetInt32ArrayData(JSObject *obj, JSContext *maybecx);
+JS_GetInt32ArrayData(JSObject *obj);
 extern JS_FRIEND_API(uint32_t *)
-JS_GetUint32ArrayData(JSObject *obj, JSContext *maybecx);
+JS_GetUint32ArrayData(JSObject *obj);
 extern JS_FRIEND_API(float *)
-JS_GetFloat32ArrayData(JSObject *obj, JSContext *maybecx);
+JS_GetFloat32ArrayData(JSObject *obj);
 extern JS_FRIEND_API(double *)
-JS_GetFloat64ArrayData(JSObject *obj, JSContext *maybecx);
+JS_GetFloat64ArrayData(JSObject *obj);
 
 /*
  * Same as above, but for any kind of ArrayBufferView. Prefer the type-specific
  * versions when possible.
  */
 extern JS_FRIEND_API(void *)
-JS_GetArrayBufferViewData(JSObject *obj, JSContext *maybecx);
+JS_GetArrayBufferViewData(JSObject *obj);
 
 /*
  * Return the ArrayBuffer underlying an ArrayBufferView. If the buffer has been
  * neutered, this will still return the neutered buffer. |obj| must be an
  * object that would return true for JS_IsArrayBufferViewObject().
  */
 extern JS_FRIEND_API(JSObject *)
-JS_GetArrayBufferViewBuffer(JSObject *obj, JSContext *maybecx);
+JS_GetArrayBufferViewBuffer(JSObject *obj);
 
 /*
- * Check whether obj supports JS_GetDataView* APIs. Note that this may fail and
- * throw an exception if a security wrapper is encountered that denies the
- * operation.
+ * Check whether obj supports JS_GetDataView* APIs.
  */
 JS_FRIEND_API(JSBool)
-JS_IsDataViewObject(JSContext *cx, JSObject *obj, JSBool *isDataView);
+JS_IsDataViewObject(JSObject *obj);
 
 /*
  * Return the byte offset of a data view into its array buffer. |obj| must be a
  * DataView.
  *
  * |obj| must have passed a JS_IsDataViewObject test, or somehow be known that
  * it would pass such a test: it is a data view or a wrapper of a data view,
- * and the unwrapping will succeed. If cx is NULL, then DEBUG builds may be
- * unable to assert when unwrapping should be disallowed.
+ * and the unwrapping will succeed.
  */
 JS_FRIEND_API(uint32_t)
-JS_GetDataViewByteOffset(JSObject *obj, JSContext *maybecx);
+JS_GetDataViewByteOffset(JSObject *obj);
 
 /*
  * Return the byte length of a data view.
  *
  * |obj| must have passed a JS_IsDataViewObject test, or somehow be known that
  * it would pass such a test: it is a data view or a wrapper of a data view,
  * and the unwrapping will succeed. If cx is NULL, then DEBUG builds may be
  * unable to assert when unwrapping should be disallowed.
  */
 JS_FRIEND_API(uint32_t)
-JS_GetDataViewByteLength(JSObject *obj, JSContext *maybecx);
+JS_GetDataViewByteLength(JSObject *obj);
 
 /*
  * Return a pointer to the beginning of the data referenced by a DataView.
  *
  * |obj| must have passed a JS_IsDataViewObject test, or somehow be known that
  * it would pass such a test: it is a data view or a wrapper of a data view,
  * and the unwrapping will succeed. If cx is NULL, then DEBUG builds may be
  * unable to assert when unwrapping should be disallowed.
  */
 JS_FRIEND_API(void *)
-JS_GetDataViewData(JSObject *obj, JSContext *maybecx);
+JS_GetDataViewData(JSObject *obj);
 
 /*
  * This struct contains metadata passed from the DOM to the JS Engine for JIT
  * optimizations on DOM property accessors. Eventually, this should be made
  * available to general JSAPI users, but we are not currently ready to do so.
  */
 typedef bool
 (* JSJitPropertyOp)(JSContext *cx, JSHandleObject thisObj,
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -169,26 +169,20 @@ fun_getProperty(JSContext *cx, HandleObj
             return true;
         }
 
         vp.set(iter.calleev());
         if (!cx->compartment->wrap(cx, vp.address()))
             return false;
 
         /*
-         * Censor the caller if we can't PUNCTURE it.
-         *
-         * NB - This will get much much nicer with bug 800915
+         * Censor the caller if we don't have full access to it.
          */
         JSObject &caller = vp.toObject();
-        JSErrorReporter reporter = JS_SetErrorReporter(cx, NULL);
-        bool punctureThrew = !UnwrapObjectChecked(cx, &caller);
-        JS_SetErrorReporter(cx, reporter);
-        if (punctureThrew) {
-            JS_ClearPendingException(cx);
+        if (caller.isWrapper() && !Wrapper::wrapperHandler(&caller)->isSafeToUnwrap()) {
             vp.setNull();
         } else if (caller.isFunction()) {
             JSFunction *callerFun = caller.toFunction();
             if (callerFun->isInterpreted() && callerFun->inStrictMode()) {
                 JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR, js_GetErrorMessage, NULL,
                                              JSMSG_CALLER_IS_STRICT);
                 return false;
             }
--- a/js/src/jstypedarray.cpp
+++ b/js/src/jstypedarray.cpp
@@ -1868,19 +1868,21 @@ class TypedArrayTemplate
              * construct the new typed array in the compartment of the buffer,
              * so that the typed array can point directly at their buffer's
              * data without crossing compartment boundaries. So we use the
              * machinery underlying NonGenericMethodGuard directly to proxy the
              * native call. We will end up with a wrapper in the origin
              * compartment for a view in the target compartment referencing the
              * ArrayBuffer in that same compartment.
              */
-            JSObject *wrapped = UnwrapObjectChecked(cx, bufobj);
-            if (!wrapped)
+            JSObject *wrapped = UnwrapObjectChecked(bufobj);
+            if (!wrapped) {
+                JS_ReportError(cx, "Permission denied to access object");
                 return NULL;
+            }
             if (wrapped->isArrayBuffer()) {
                 /*
                  * And for even more fun, the new view's prototype should be
                  * set to the origin compartment's prototype object, not the
                  * target's (specifically, the actual view in the target
                  * compartment will use as its prototype a wrapper around the
                  * origin compartment's view.prototype object).
                  *
@@ -3136,50 +3138,41 @@ JSFunctionSpec _typedArray::jsfuncs[] = 
                                JSObject *arrayBuffer_, uint32_t byteoffset, int32_t length)  \
   {                                                                                          \
       MOZ_ASSERT(byteoffset <= INT32_MAX);                                                   \
       Rooted<JSObject*> arrayBuffer(cx, arrayBuffer_);                                       \
       Rooted<JSObject*> proto(cx, NULL);                                                     \
       return TypedArrayTemplate<NativeType>::fromBuffer(cx, arrayBuffer, byteoffset, length, \
                                                         proto);                              \
   }                                                                                          \
-  JS_FRIEND_API(JSBool) JS_Is ## Name ## Array(JSObject *obj, JSContext *cx)                 \
+  JS_FRIEND_API(JSBool) JS_Is ## Name ## Array(JSObject *obj)                                \
   {                                                                                          \
-      MOZ_ASSERT(!cx->isExceptionPending());                                                 \
-      if (!(obj = UnwrapObjectChecked(cx, obj))) {                                           \
-          cx->clearPendingException();                                                       \
+      if (!(obj = UnwrapObjectChecked(obj)))                                                 \
           return false;                                                                      \
-      }                                                                                      \
       Class *clasp = obj->getClass();                                                        \
       return (clasp == &TypedArray::classes[TypedArrayTemplate<NativeType>::ArrayTypeID()]); \
   }
 
 IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Int8, int8_t)
 IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Uint8, uint8_t)
 IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Uint8Clamped, uint8_clamped)
 IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Int16, int16_t)
 IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Uint16, uint16_t)
 IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Int32, int32_t)
 IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Uint32, uint32_t)
 IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Float32, float)
 IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Float64, double)
 
 #define IMPL_TYPED_ARRAY_COMBINED_UNWRAPPERS(Name, ExternalType, InternalType)              \
-  JS_FRIEND_API(JSObject *) JS_GetObjectAs ## Name ## Array(JSContext *cx,                  \
-                                                            JSObject *obj,                  \
+  JS_FRIEND_API(JSObject *) JS_GetObjectAs ## Name ## Array(JSObject *obj,                  \
                                                             uint32_t *length,               \
                                                             ExternalType **data)            \
   {                                                                                         \
-      if (obj->isWrapper()) {                                                               \
-          MOZ_ASSERT(!cx->isExceptionPending());                                            \
-          if (!(obj = UnwrapObjectChecked(cx, obj))) {                                      \
-              cx->clearPendingException();                                                  \
-              return NULL;                                                                  \
-          }                                                                                 \
-      }                                                                                     \
+      if (!(obj = UnwrapObjectChecked(obj)))                                                \
+          return NULL;                                                                      \
                                                                                             \
       Class *clasp = obj->getClass();                                                       \
       if (clasp != &TypedArray::classes[TypedArrayTemplate<InternalType>::ArrayTypeID()])   \
           return NULL;                                                                      \
                                                                                             \
       *length = TypedArray::length(obj);                                                    \
       *data = static_cast<ExternalType *>(TypedArray::viewData(obj));                       \
                                                                                             \
@@ -3566,86 +3559,52 @@ js_InitTypedArrayClasses(JSContext *cx, 
         return NULL;
     }
 
     return InitArrayBufferClass(cx);
 }
 
 /* JS Friend API */
 
-// The typed array friend API defines a number of accessor functions that want
-// to unwrap an argument, but in certain rare cases may not have a cx available
-// and so pass in NULL instead. Use UnwrapObjectChecked when possible.
-static JSObject *
-CheckedUnwrap(JSContext *cx, JSObject *obj)
+JS_FRIEND_API(JSBool)
+JS_IsArrayBufferObject(JSObject *obj)
 {
-    if (!cx)
-        return UnwrapObject(obj);
-    MOZ_ASSERT(!cx->isExceptionPending());
-    obj = UnwrapObjectChecked(cx, obj);
-    MOZ_ASSERT(obj);
-    return obj;
+    obj = UnwrapObjectChecked(obj);
+    return obj ? obj->isArrayBuffer() : false;
 }
 
 JS_FRIEND_API(JSBool)
-JS_IsArrayBufferObject(JSObject *objArg, JSContext *cx)
+JS_IsTypedArrayObject(JSObject *obj)
 {
-    RootedObject obj_(cx, objArg);
-    MOZ_ASSERT(!cx->isExceptionPending());
-    JSObject *obj = UnwrapObjectChecked(cx, obj_);
-    if (!obj) {
-        cx->clearPendingException();
-        return false;
-    }
-    return obj->isArrayBuffer();
+    obj = UnwrapObjectChecked(obj);
+    return obj ? obj->isTypedArray() : false;
 }
 
 JS_FRIEND_API(JSBool)
-JS_IsTypedArrayObject(JSObject *objArg, JSContext *cx)
+JS_IsArrayBufferViewObject(JSObject *obj)
 {
-    RootedObject obj_(cx, objArg);
-    MOZ_ASSERT(!cx->isExceptionPending());
-    JSObject *obj = UnwrapObjectChecked(cx, obj_);
-    if (!obj) {
-        cx->clearPendingException();
-        return false;
-    }
-    return obj->isTypedArray();
-}
-
-JS_FRIEND_API(JSBool)
-JS_IsArrayBufferViewObject(JSObject *objArg, JSContext *cx)
-{
-    RootedObject obj_(cx, objArg);
-    MOZ_ASSERT(!cx->isExceptionPending());
-    JSObject *obj = UnwrapObjectChecked(cx, obj_);
-    if (!obj) {
-        cx->clearPendingException();
-        return false;
-    }
-    return obj->isTypedArray() || obj->isDataView();
+    obj = UnwrapObjectChecked(obj);
+    return obj ? (obj->isTypedArray() || obj->isDataView()) : false;
 }
 
 JS_FRIEND_API(uint32_t)
-JS_GetArrayBufferByteLength(JSObject *obj, JSContext *maybecx)
+JS_GetArrayBufferByteLength(JSObject *obj)
 {
-    obj = CheckedUnwrap(maybecx, obj);
-    if (!obj)
-        return 0;
-    return obj->asArrayBuffer().byteLength();
+    obj = UnwrapObjectChecked(obj);
+    return obj ? obj->asArrayBuffer().byteLength() : 0;
 }
 
 JS_FRIEND_API(uint8_t *)
-JS_GetArrayBufferData(JSObject *obj, JSContext *maybecx)
+JS_GetArrayBufferData(JSObject *obj)
 {
-    obj = CheckedUnwrap(maybecx, obj);
+    obj = UnwrapObjectChecked(obj);
     if (!obj)
         return NULL;
     ArrayBufferObject &buffer = obj->asArrayBuffer();
-    if (!buffer.uninlineData(maybecx))
+    if (!buffer.uninlineData(NULL))
         return NULL;
     return buffer.dataPointer();
 }
 
 JS_FRIEND_API(JSObject *)
 JS_NewArrayBuffer(JSContext *cx, uint32_t nbytes)
 {
     JS_ASSERT(nbytes <= INT32_MAX);
@@ -3675,271 +3634,258 @@ JS_AllocateArrayBufferContents(JSContext
     *data = reinterpret_cast<uint8_t*>(header->elements());
     return true;
 }
 
 JS_PUBLIC_API(JSBool)
 JS_StealArrayBufferContents(JSContext *cx, JSObject *obj, void **contents,
                             uint8_t **data)
 {
-    if (!(obj = UnwrapObjectChecked(cx, obj)))
+    if (!(obj = UnwrapObjectChecked(obj)))
         return false;
 
     if (!obj->isArrayBuffer()) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_TYPED_ARRAY_BAD_ARGS);
         return false;
     }
 
     if (!ArrayBufferObject::stealContents(cx, obj, contents, data))
         return false;
 
     return true;
 }
 
 JS_FRIEND_API(uint32_t)
-JS_GetTypedArrayLength(JSObject *obj, JSContext *maybecx)
+JS_GetTypedArrayLength(JSObject *obj)
 {
-    obj = CheckedUnwrap(maybecx, obj);
+    obj = UnwrapObjectChecked(obj);
     if (!obj)
         return 0;
     JS_ASSERT(obj->isTypedArray());
     return TypedArray::length(obj);
 }
 
 JS_FRIEND_API(uint32_t)
-JS_GetTypedArrayByteOffset(JSObject *obj, JSContext *maybecx)
+JS_GetTypedArrayByteOffset(JSObject *obj)
 {
-    obj = CheckedUnwrap(maybecx, obj);
+    obj = UnwrapObjectChecked(obj);
     if (!obj)
         return 0;
     JS_ASSERT(obj->isTypedArray());
     return TypedArray::byteOffset(obj);
 }
 
 JS_FRIEND_API(uint32_t)
-JS_GetTypedArrayByteLength(JSObject *obj, JSContext *maybecx)
+JS_GetTypedArrayByteLength(JSObject *obj)
 {
-    obj = CheckedUnwrap(maybecx, obj);
+    obj = UnwrapObjectChecked(obj);
     if (!obj)
         return 0;
     JS_ASSERT(obj->isTypedArray());
     return TypedArray::byteLength(obj);
 }
 
 JS_FRIEND_API(JSArrayBufferViewType)
-JS_GetTypedArrayType(JSObject *obj, JSContext *maybecx)
+JS_GetTypedArrayType(JSObject *obj)
 {
-    obj = CheckedUnwrap(maybecx, obj);
+    obj = UnwrapObjectChecked(obj);
     if (!obj)
         return ArrayBufferView::TYPE_MAX;
     JS_ASSERT(obj->isTypedArray());
     return static_cast<JSArrayBufferViewType>(TypedArray::type(obj));
 }
 
 JS_FRIEND_API(int8_t *)
-JS_GetInt8ArrayData(JSObject *obj, JSContext *maybecx)
+JS_GetInt8ArrayData(JSObject *obj)
 {
-    obj = CheckedUnwrap(maybecx, obj);
+    obj = UnwrapObjectChecked(obj);
     if (!obj)
         return NULL;
     JS_ASSERT(obj->isTypedArray());
     JS_ASSERT(TypedArray::type(obj) == ArrayBufferView::TYPE_INT8);
     return static_cast<int8_t *>(TypedArray::viewData(obj));
 }
 
 JS_FRIEND_API(uint8_t *)
-JS_GetUint8ArrayData(JSObject *obj, JSContext *maybecx)
+JS_GetUint8ArrayData(JSObject *obj)
 {
-    obj = CheckedUnwrap(maybecx, obj);
+    obj = UnwrapObjectChecked(obj);
     if (!obj)
         return NULL;
     JS_ASSERT(obj->isTypedArray());
     JS_ASSERT(TypedArray::type(obj) == ArrayBufferView::TYPE_UINT8);
     return static_cast<uint8_t *>(TypedArray::viewData(obj));
 }
 
 JS_FRIEND_API(uint8_t *)
-JS_GetUint8ClampedArrayData(JSObject *obj, JSContext *maybecx)
+JS_GetUint8ClampedArrayData(JSObject *obj)
 {
-    obj = CheckedUnwrap(maybecx, obj);
+    obj = UnwrapObjectChecked(obj);
     if (!obj)
         return NULL;
     JS_ASSERT(obj->isTypedArray());
     JS_ASSERT(TypedArray::type(obj) == ArrayBufferView::TYPE_UINT8_CLAMPED);
     return static_cast<uint8_t *>(TypedArray::viewData(obj));
 }
 
 JS_FRIEND_API(int16_t *)
-JS_GetInt16ArrayData(JSObject *obj, JSContext *maybecx)
+JS_GetInt16ArrayData(JSObject *obj)
 {
-    obj = CheckedUnwrap(maybecx, obj);
+    obj = UnwrapObjectChecked(obj);
     if (!obj)
         return NULL;
     JS_ASSERT(obj->isTypedArray());
     JS_ASSERT(TypedArray::type(obj) == ArrayBufferView::TYPE_INT16);
     return static_cast<int16_t *>(TypedArray::viewData(obj));
 }
 
 JS_FRIEND_API(uint16_t *)
-JS_GetUint16ArrayData(JSObject *obj, JSContext *maybecx)
+JS_GetUint16ArrayData(JSObject *obj)
 {
-    obj = CheckedUnwrap(maybecx, obj);
+    obj = UnwrapObjectChecked(obj);
     if (!obj)
         return NULL;
     JS_ASSERT(obj->isTypedArray());
     JS_ASSERT(TypedArray::type(obj) == ArrayBufferView::TYPE_UINT16);
     return static_cast<uint16_t *>(TypedArray::viewData(obj));
 }
 
 JS_FRIEND_API(int32_t *)
-JS_GetInt32ArrayData(JSObject *obj, JSContext *maybecx)
+JS_GetInt32ArrayData(JSObject *obj)
 {
-    obj = CheckedUnwrap(maybecx, obj);
+    obj = UnwrapObjectChecked(obj);
     if (!obj)
         return NULL;
     JS_ASSERT(obj->isTypedArray());
     JS_ASSERT(TypedArray::type(obj) == ArrayBufferView::TYPE_INT32);
     return static_cast<int32_t *>(TypedArray::viewData(obj));
 }
 
 JS_FRIEND_API(uint32_t *)
-JS_GetUint32ArrayData(JSObject *obj, JSContext *maybecx)
+JS_GetUint32ArrayData(JSObject *obj)
 {
-    obj = CheckedUnwrap(maybecx, obj);
+    obj = UnwrapObjectChecked(obj);
     if (!obj)
         return NULL;
     JS_ASSERT(obj->isTypedArray());
     JS_ASSERT(TypedArray::type(obj) == ArrayBufferView::TYPE_UINT32);
     return static_cast<uint32_t *>(TypedArray::viewData(obj));
 }
 
 JS_FRIEND_API(float *)
-JS_GetFloat32ArrayData(JSObject *obj, JSContext *maybecx)
+JS_GetFloat32ArrayData(JSObject *obj)
 {
-    obj = CheckedUnwrap(maybecx, obj);
+    obj = UnwrapObjectChecked(obj);
     if (!obj)
         return NULL;
     JS_ASSERT(obj->isTypedArray());
     JS_ASSERT(TypedArray::type(obj) == ArrayBufferView::TYPE_FLOAT32);
     return static_cast<float *>(TypedArray::viewData(obj));
 }
 
 JS_FRIEND_API(double *)
-JS_GetFloat64ArrayData(JSObject *obj, JSContext *maybecx)
+JS_GetFloat64ArrayData(JSObject *obj)
 {
-    obj = CheckedUnwrap(maybecx, obj);
+    obj = UnwrapObjectChecked(obj);
     if (!obj)
         return NULL;
     JS_ASSERT(obj->isTypedArray());
     JS_ASSERT(TypedArray::type(obj) == ArrayBufferView::TYPE_FLOAT64);
     return static_cast<double *>(TypedArray::viewData(obj));
 }
 
 JS_FRIEND_API(JSBool)
-JS_IsDataViewObject(JSContext *cx, JSObject *objArg, JSBool *isDataView)
+JS_IsDataViewObject(JSObject *obj)
 {
-    RootedObject obj_(cx, objArg);
-    JSObject *obj = CheckedUnwrap(cx, obj_);
-    if (!obj)
-        return false;
-    *isDataView = obj->isDataView();
-    return true;
+    obj = UnwrapObjectChecked(obj);
+    return obj ? obj->isDataView() : false;
 }
 
 JS_FRIEND_API(uint32_t)
-JS_GetDataViewByteOffset(JSObject *obj, JSContext *maybecx)
+JS_GetDataViewByteOffset(JSObject *obj)
 {
-    obj = CheckedUnwrap(maybecx, obj);
+    obj = UnwrapObjectChecked(obj);
     if (!obj)
         return 0;
     return obj->asDataView().byteOffset();
 }
 
 JS_FRIEND_API(void *)
-JS_GetDataViewData(JSObject *obj, JSContext *maybecx)
+JS_GetDataViewData(JSObject *obj)
 {
-    obj = CheckedUnwrap(maybecx, obj);
+    obj = UnwrapObjectChecked(obj);
     if (!obj)
         return NULL;
     JS_ASSERT(obj->isDataView());
     return obj->asDataView().dataPointer();
 }
 
 JS_FRIEND_API(uint32_t)
-JS_GetDataViewByteLength(JSObject *obj, JSContext *maybecx)
+JS_GetDataViewByteLength(JSObject *obj)
 {
-    obj = CheckedUnwrap(maybecx, obj);
+    obj = UnwrapObjectChecked(obj);
     if (!obj)
         return 0;
     JS_ASSERT(obj->isDataView());
     return obj->asDataView().byteLength();
 }
 
 JS_FRIEND_API(void *)
-JS_GetArrayBufferViewData(JSObject *obj, JSContext *maybecx)
+JS_GetArrayBufferViewData(JSObject *obj)
 {
-    obj = CheckedUnwrap(maybecx, obj);
+    obj = UnwrapObjectChecked(obj);
     if (!obj)
         return NULL;
     JS_ASSERT(obj->isTypedArray() || obj->isDataView());
     return obj->isDataView() ? obj->asDataView().dataPointer() : TypedArray::viewData(obj);
 }
 
 JS_FRIEND_API(JSObject *)
-JS_GetArrayBufferViewBuffer(JSObject *obj, JSContext *maybecx)
+JS_GetArrayBufferViewBuffer(JSObject *obj)
 {
-    obj = CheckedUnwrap(maybecx, obj);
+    obj = UnwrapObjectChecked(obj);
     if (!obj)
         return NULL;
     JS_ASSERT(obj->isTypedArray() || obj->isDataView());
     return &obj->getFixedSlot(BufferView::BUFFER_SLOT).toObject();
 }
 
 JS_FRIEND_API(uint32_t)
-JS_GetArrayBufferViewByteLength(JSObject *obj, JSContext *maybecx)
+JS_GetArrayBufferViewByteLength(JSObject *obj)
 {
-    obj = CheckedUnwrap(maybecx, obj);
+    obj = UnwrapObjectChecked(obj);
     if (!obj)
         return 0;
     JS_ASSERT(obj->isTypedArray() || obj->isDataView());
     return obj->isDataView()
            ? obj->asDataView().byteLength()
            : TypedArray::byteLengthValue(obj).toInt32();
 }
 
 JS_FRIEND_API(JSObject *)
-JS_GetObjectAsArrayBufferView(JSContext *cx, JSObject *obj,
-                              uint32_t *length, uint8_t **data)
+JS_GetObjectAsArrayBufferView(JSObject *obj, uint32_t *length, uint8_t **data)
 {
-    if (obj->isWrapper()) {
-        if (!(obj = UnwrapObjectChecked(cx, obj))) {
-            cx->clearPendingException();
-            return NULL;
-        }
-    }
+    if (!(obj = UnwrapObjectChecked(obj)))
+        return NULL;
     if (!(obj->isTypedArray() || obj->isDataView()))
         return NULL;
 
     *length = obj->isDataView() ? obj->asDataView().byteLength()
                                 : TypedArray::byteLengthValue(obj).toInt32();
 
     *data = static_cast<uint8_t *>(obj->isDataView() ? obj->asDataView().dataPointer()
                                                      : TypedArray::viewData(obj));
     return obj;
 }
 
 JS_FRIEND_API(JSObject *)
-JS_GetObjectAsArrayBuffer(JSContext *cx, JSObject *obj, uint32_t *length, uint8_t **data)
+JS_GetObjectAsArrayBuffer(JSObject *obj, uint32_t *length, uint8_t **data)
 {
-    if (obj->isWrapper()) {
-        if (!(obj = UnwrapObjectChecked(cx, obj))) {
-            cx->clearPendingException();
-            return NULL;
-        }
-    }
+   if (!(obj = UnwrapObjectChecked(obj)))
+       return NULL;
     if (!obj->isArrayBuffer())
         return NULL;
 
     *length = obj->asArrayBuffer().byteLength();
     *data = obj->asArrayBuffer().dataPointer();
 
     return obj;
 }
--- a/js/src/jswrapper.cpp
+++ b/js/src/jswrapper.cpp
@@ -104,43 +104,38 @@ js::UnwrapObject(JSObject *wrapped, bool
         wrapped = GetProxyPrivate(wrapped).toObjectOrNull();
     }
     if (flagsp)
         *flagsp = flags;
     return wrapped;
 }
 
 JS_FRIEND_API(JSObject *)
-js::UnwrapObjectChecked(JSContext *cx, RawObject objArg)
+js::UnwrapObjectChecked(RawObject obj)
 {
-    RootedObject obj(cx, objArg);
     while (true) {
         JSObject *wrapper = obj;
-        obj = UnwrapOneChecked(cx, obj);
+        obj = UnwrapOneChecked(obj);
         if (!obj || obj == wrapper)
             return obj;
     }
 }
 
 JS_FRIEND_API(JSObject *)
-js::UnwrapOneChecked(JSContext *cx, HandleObject obj)
+js::UnwrapOneChecked(RawObject obj)
 {
     // Checked unwraps should never unwrap outer windows.
     if (!obj->isWrapper() ||
         JS_UNLIKELY(!!obj->getClass()->ext.innerObject))
     {
         return obj;
     }
 
     Wrapper *handler = Wrapper::wrapperHandler(obj);
-    if (!handler->isSafeToUnwrap()) {
-        JS_ReportError(cx, "Permission denied to access object");
-        return NULL;
-    }
-    return Wrapper::wrappedObject(obj);
+    return handler->isSafeToUnwrap() ? Wrapper::wrappedObject(obj) : NULL;
 }
 
 bool
 js::IsCrossCompartmentWrapper(RawObject wrapper)
 {
     return wrapper->isWrapper() &&
            !!(Wrapper::wrapperHandler(wrapper)->flags() & Wrapper::CROSS_COMPARTMENT);
 }
--- a/js/src/jswrapper.h
+++ b/js/src/jswrapper.h
@@ -250,22 +250,22 @@ IsWrapper(RawObject obj)
 JS_FRIEND_API(JSObject *)
 UnwrapObject(JSObject *obj, bool stopAtOuter = true, unsigned *flagsp = NULL);
 
 // Given a JSObject, returns that object stripped of wrappers. At each stage,
 // the security wrapper has the opportunity to veto the unwrap. Since checked
 // code should never be unwrapping outer window wrappers, we always stop at
 // outer windows.
 JS_FRIEND_API(JSObject *)
-UnwrapObjectChecked(JSContext *cx, RawObject obj);
+UnwrapObjectChecked(RawObject obj);
 
 // Unwrap only the outermost security wrapper, with the same semantics as
 // above. This is the checked version of Wrapper::wrappedObject.
 JS_FRIEND_API(JSObject *)
-UnwrapOneChecked(JSContext *cx, HandleObject obj);
+UnwrapOneChecked(RawObject obj);
 
 JS_FRIEND_API(bool)
 IsCrossCompartmentWrapper(RawObject obj);
 
 bool
 IsDeadProxyObject(RawObject obj);
 
 JSObject *
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -1814,19 +1814,21 @@ Debugger::unwrapDebuggeeArgument(JSConte
     if (obj->getClass() == &DebuggerObject_class) {
         Value rv = v;
         if (!unwrapDebuggeeValue(cx, &rv))
             return NULL;
         obj = &rv.toObject();
     }
 
     /* If we have a cross-compartment wrapper, dereference as far as is secure. */
-    obj = UnwrapObjectChecked(cx, obj);
-    if (!obj)
+    obj = UnwrapObjectChecked(obj);
+    if (!obj) {
+        JS_ReportError(cx, "Permission denied to access object");
         return NULL;
+    }
 
     /* If that produced an outer window, innerize it. */
     obj = GetInnerObject(cx, obj);
     if (!obj)
         return NULL;
 
     /* If that didn't produce a global object, it's an error. */
     if (!obj->isGlobal()) {
@@ -4460,28 +4462,18 @@ DebuggerObject_evalInGlobalWithBindings(
     return DebuggerGenericEval(cx, "Debugger.Object.prototype.evalInGlobalWithBindings",
                                args[0], &args[1], vp, dbg, referent, NULL);
 }
 
 static JSBool
 DebuggerObject_unwrap(JSContext *cx, unsigned argc, Value *vp)
 {
     THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, "unwrap", args, dbg, referent);
-    JSObject *unwrapped = UnwrapOneChecked(cx, referent);
+    JSObject *unwrapped = UnwrapOneChecked(referent);
     if (!unwrapped) {
-        // If we were terminated, then pass that along.
-        if (!cx->isExceptionPending())
-            return false;
-
-        // If the unwrap operation threw an exception, assume it's a
-        // security exception, and return null. It seems like the wrappers
-        // in use in Firefox just call JS_ReportError, so we have no way to
-        // distinguish genuine should-not-unwrap errors from other kinds of
-        // errors.
-        cx->clearPendingException();
         vp->setNull();
         return true;
     }
 
     *vp = ObjectValue(*unwrapped);
     if (!dbg->wrapDebuggeeValue(cx, vp))
         return false;
     return true;
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -2706,17 +2706,17 @@ nsXPCComponents_Utils::LookupMethod(cons
         return NS_ERROR_XPC_BAD_CONVERT_JS;
     JSString *methodName = name.toString();
     jsid methodId = INTERNED_STRING_TO_JSID(cx, JS_InternJSString(cx, methodName));
 
     // If |obj| is a cross-compartment wrapper, try to puncture it. If this fails,
     // we don't have full access to the other compartment, in which case we throw.
     // Otherwise, enter the compartment.
     if (js::IsCrossCompartmentWrapper(obj)) {
-        obj = js::UnwrapOneChecked(cx, obj);
+        obj = js::UnwrapOneChecked(obj);
         if (!obj)
             return NS_ERROR_XPC_BAD_CONVERT_JS;
     }
 
     {
         // Enter the target compartment.
         JSAutoCompartment ac(cx, obj);
 
@@ -3858,17 +3858,17 @@ nsXPCComponents_Utils::EvalInSandbox(con
 
 nsresult
 xpc_EvalInSandbox(JSContext *cx, JSObject *sandbox, const nsAString& source,
                   const char *filename, int32_t lineNo,
                   JSVersion jsVersion, bool returnStringOnly, jsval *rval)
 {
     JS_AbortIfWrongThread(JS_GetRuntime(cx));
 
-    sandbox = js::UnwrapObjectChecked(cx, sandbox);
+    sandbox = js::UnwrapObjectChecked(sandbox);
     if (!sandbox || js::GetObjectJSClass(sandbox) != &SandboxClass) {
         return NS_ERROR_INVALID_ARG;
     }
 
     nsIScriptObjectPrincipal *sop =
         (nsIScriptObjectPrincipal*)xpc_GetJSPrivate(sandbox);
     NS_ASSERTION(sop, "Invalid sandbox passed");
     nsCOMPtr<nsIPrincipal> prin = sop->GetPrincipal();
--- a/js/xpconnect/src/XPCConvert.cpp
+++ b/js/xpconnect/src/XPCConvert.cpp
@@ -1478,18 +1478,17 @@ failure:
 
 
 
 // Check that the tag part of the type matches the type
 // of the array. If the check succeeds, check that the size
 // of the output does not exceed UINT32_MAX bytes. Allocate
 // the memory and copy the elements by memcpy.
 static JSBool
-CheckTargetAndPopulate(JSContext *cx,
-                       const nsXPTType& type,
+CheckTargetAndPopulate(const nsXPTType& type,
                        uint8_t requiredType,
                        size_t typeSize,
                        uint32_t count,
                        JSObject* tArr,
                        void** output,
                        nsresult* pErr)
 {
     // Check that the element type expected by the interface matches
@@ -1510,113 +1509,112 @@ CheckTargetAndPopulate(JSContext *cx,
     size_t byteSize = count * typeSize;
     if (count > max || !(*output = nsMemory::Alloc(byteSize))) {
         if (pErr)
             *pErr = NS_ERROR_OUT_OF_MEMORY;
 
         return false;
     }
 
-    memcpy(*output, JS_GetArrayBufferViewData(tArr, cx), byteSize);
+    memcpy(*output, JS_GetArrayBufferViewData(tArr), byteSize);
     return true;
 }
 
 // Fast conversion of typed arrays to native using memcpy.
 // No float or double canonicalization is done. Called by
 // JSarray2Native whenever a TypedArray is met. ArrayBuffers
 // are not accepted; create a properly typed array view on them
 // first. The element type of array must match the XPCOM
 // type in size, type and signedness exactly. As an exception,
 // Uint8ClampedArray is allowed for arrays of uint8_t.
 
 // static
 JSBool
-XPCConvert::JSTypedArray2Native(JSContext* cx,
-                                void** d,
+XPCConvert::JSTypedArray2Native(void** d,
                                 JSObject* jsArray,
                                 uint32_t count,
                                 const nsXPTType& type,
                                 nsresult* pErr)
 {
     NS_ABORT_IF_FALSE(jsArray, "bad param");
     NS_ABORT_IF_FALSE(d, "bad param");
-    NS_ABORT_IF_FALSE(JS_IsTypedArrayObject(jsArray, cx), "not a typed array");
+    NS_ABORT_IF_FALSE(JS_IsTypedArrayObject(jsArray), "not a typed array");
 
     // Check the actual length of the input array against the
     // given size_is.
-    uint32_t len = JS_GetTypedArrayLength(jsArray, cx);
+    uint32_t len = JS_GetTypedArrayLength(jsArray);
     if (len < count) {
         if (pErr)
             *pErr = NS_ERROR_XPC_NOT_ENOUGH_ELEMENTS_IN_ARRAY;
 
         return false;
     }
 
     void* output = nullptr;
 
-    switch (JS_GetTypedArrayType(jsArray, cx)) {
+    switch (JS_GetTypedArrayType(jsArray)) {
     case js::ArrayBufferView::TYPE_INT8:
-        if (!CheckTargetAndPopulate(cx, nsXPTType::T_I8, type,
+        if (!CheckTargetAndPopulate(nsXPTType::T_I8, type,
                                     sizeof(int8_t), count,
                                     jsArray, &output, pErr)) {
             return false;
         }
         break;
 
     case js::ArrayBufferView::TYPE_UINT8:
     case js::ArrayBufferView::TYPE_UINT8_CLAMPED:
-        if (!CheckTargetAndPopulate(cx, nsXPTType::T_U8, type,
+        if (!CheckTargetAndPopulate(nsXPTType::T_U8, type,
                                     sizeof(uint8_t), count,
                                     jsArray, &output, pErr)) {
             return false;
         }
         break;
 
     case js::ArrayBufferView::TYPE_INT16:
-        if (!CheckTargetAndPopulate(cx, nsXPTType::T_I16, type,
+        if (!CheckTargetAndPopulate(nsXPTType::T_I16, type,
                                     sizeof(int16_t), count,
                                     jsArray, &output, pErr)) {
             return false;
         }
         break;
 
     case js::ArrayBufferView::TYPE_UINT16:
-        if (!CheckTargetAndPopulate(cx, nsXPTType::T_U16, type,
+        if (!CheckTargetAndPopulate(nsXPTType::T_U16, type,
                                     sizeof(uint16_t), count,
                                     jsArray, &output, pErr)) {
             return false;
         }
         break;
 
     case js::ArrayBufferView::TYPE_INT32:
-        if (!CheckTargetAndPopulate(cx, nsXPTType::T_I32, type,
+        if (!CheckTargetAndPopulate(nsXPTType::T_I32, type,
                                     sizeof(int32_t), count,
                                     jsArray, &output, pErr)) {
             return false;
         }
         break;
 
     case js::ArrayBufferView::TYPE_UINT32:
-        if (!CheckTargetAndPopulate(cx, nsXPTType::T_U32, type,
+        if (!CheckTargetAndPopulate(nsXPTType::T_U32, type,
                                     sizeof(uint32_t), count,
                                     jsArray, &output, pErr)) {
             return false;
         }
         break;
 
     case js::ArrayBufferView::TYPE_FLOAT32:
-        if (!CheckTargetAndPopulate(cx, nsXPTType::T_FLOAT, type,
+        if (!CheckTargetAndPopulate(nsXPTType::T_FLOAT, type,
                                     sizeof(float), count,
                                     jsArray, &output, pErr)) {
             return false;
         }
         break;
 
     case js::ArrayBufferView::TYPE_FLOAT64:
-        if (!CheckTargetAndPopulate(cx, nsXPTType::T_DOUBLE, type,
+        if (!CheckTargetAndPopulate(nsXPTType::T_DOUBLE, type,
                                     sizeof(double), count,
                                     jsArray, &output, pErr)) {
             return false;
         }
         break;
 
     // Yet another array type was defined? It is not supported yet...
     default:
@@ -1660,18 +1658,18 @@ XPCConvert::JSArray2Native(JSContext* cx
         if (pErr)
             *pErr = NS_ERROR_XPC_CANT_CONVERT_PRIMITIVE_TO_ARRAY;
         return false;
     }
 
     JSObject* jsarray = &s.toObject();
 
     // If this is a typed array, then try a fast conversion with memcpy.
-    if (JS_IsTypedArrayObject(jsarray, cx)) {
-        return JSTypedArray2Native(cx, d, jsarray, count, type, pErr);
+    if (JS_IsTypedArrayObject(jsarray)) {
+        return JSTypedArray2Native(d, jsarray, count, type, pErr);
     }
 
     if (!JS_IsArrayObject(cx, jsarray)) {
         if (pErr)
             *pErr = NS_ERROR_XPC_CANT_CONVERT_OBJECT_TO_ARRAY;
         return false;
     }
 
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -3363,18 +3363,17 @@ public:
                                  jsval* d, const void** s,
                                  const nsXPTType& type, const nsID* iid,
                                  uint32_t count, nsresult* pErr);
 
     static JSBool JSArray2Native(JSContext* cx, void** d, jsval s,
                                  uint32_t count, const nsXPTType& type,
                                  const nsID* iid, nsresult* pErr);
 
-    static JSBool JSTypedArray2Native(JSContext* cx,
-                                      void** d,
+    static JSBool JSTypedArray2Native(void** d,
                                       JSObject* jsarray,
                                       uint32_t count,
                                       const nsXPTType& type,
                                       nsresult* pErr);
 
     static JSBool NativeStringWithSize2JS(JSContext* cx,
                                           jsval* d, const void* s,
                                           const nsXPTType& type,
--- a/js/xpconnect/wrappers/AccessCheck.cpp
+++ b/js/xpconnect/wrappers/AccessCheck.cpp
@@ -349,17 +349,17 @@ ExposedPropertiesOnly::check(JSContext *
     JSAutoCompartment ac(cx, wrappedObject);
 
     JSBool found = false;
     if (!JS_HasPropertyById(cx, wrappedObject, exposedPropsId, &found))
         return false;
 
     // Always permit access to "length" and indexed properties of arrays.
     if ((JS_IsArrayObject(cx, wrappedObject) ||
-         JS_IsTypedArrayObject(wrappedObject, cx)) &&
+         JS_IsTypedArrayObject(wrappedObject)) &&
         ((JSID_IS_INT(id) && JSID_TO_INT(id) >= 0) ||
          (JSID_IS_STRING(id) && JS_FlatStringEqualsAscii(JSID_TO_FLAT_STRING(id), "length")))) {
         return true; // Allow
     }
 
     // If no __exposedProps__ existed, deny access.
     if (!found) {
         // Everything below here needs to be done in the wrapper's compartment.