Bug 800915 - Remove the cx parameter and simplify various APIs. r=sfink,bz
authorBobby Holley <bobbyholley@gmail.com>
Mon, 12 Nov 2012 17:35:32 -0800
changeset 120984 de9fff3a523240b175c0aca822911011b926d64d
parent 120983 c567df2244f59d53a71467afa461a12adad8ba7f
child 120985 0d124d4f28b0d3365ae7c4ec0ab4b2a99e399405
push id1997
push userakeybl@mozilla.com
push dateMon, 07 Jan 2013 21:25:26 +0000
treeherdermozilla-beta@4baf45cdcf21 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink, bz
bugs800915
milestone19.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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
@@ -4316,17 +4316,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);
 
@@ -4428,17 +4428,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,
@@ -4448,17 +4448,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
@@ -2585,17 +2585,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.