Bug 747935 - Part 2: Rewrite dom::TypedArray to use JS_UnwrapObjectAs*Array(). (r=bz)
☠☠ backed out by 598bdf564949 ☠ ☠
authorEric Faust <efaust@mozilla.com>
Tue, 31 Jul 2012 20:06:35 -0700
changeset 101061 97a1463cde9c2d03ea22e63e992368cba0e70096
parent 101060 6e78bc0145ee413876a0ee1da79bc3140e155a8a
child 101062 9097d0b3acc63faf3e6497c8e3f521400e64b0b2
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersbz
bugs747935
milestone17.0a1
Bug 747935 - Part 2: Rewrite dom::TypedArray to use JS_UnwrapObjectAs*Array(). (r=bz)
content/base/src/nsXMLHttpRequest.cpp
content/canvas/src/WebGLContext.h
content/canvas/src/WebGLContextGL.cpp
content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
dom/bindings/TypedArray.h
dom/workers/XMLHttpRequest.h
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -2598,18 +2598,18 @@ GetRequestBody(nsIXHRSendable* aSendable
 
 static nsresult
 GetRequestBody(ArrayBuffer* aArrayBuffer, nsIInputStream** aResult,
                nsACString& aContentType, nsACString& aCharset)
 {
   aContentType.SetIsVoid(true);
   aCharset.Truncate();
 
-  PRInt32 length = aArrayBuffer->mLength;
-  char* data = reinterpret_cast<char*>(aArrayBuffer->mData);
+  PRInt32 length = aArrayBuffer->Length();
+  char* data = reinterpret_cast<char*>(aArrayBuffer->Data());
 
   nsCOMPtr<nsIInputStream> stream;
   nsresult rv = NS_NewByteInputStream(getter_AddRefs(stream), data, length,
                                       NS_ASSIGNMENT_COPY);
   NS_ENSURE_SUCCESS(rv, rv);
 
   stream.forget(aResult);
 
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -887,129 +887,129 @@ public:
     void Uniform1f(WebGLUniformLocation* location, WebGLfloat x);
     void Uniform2f(WebGLUniformLocation* location, WebGLfloat x, WebGLfloat y);
     void Uniform3f(WebGLUniformLocation* location, WebGLfloat x, WebGLfloat y,
                    WebGLfloat z);
     void Uniform4f(WebGLUniformLocation* location, WebGLfloat x, WebGLfloat y,
                    WebGLfloat z, WebGLfloat w);
     
     void Uniform1iv(WebGLUniformLocation* location, dom::Int32Array& arr) {
-        Uniform1iv_base(location, arr.mLength, arr.mData);
+        Uniform1iv_base(location, arr.Length(), arr.Data());
     }
     void Uniform1iv(WebGLUniformLocation* location,
                     const dom::Sequence<WebGLint>& arr) {
         Uniform1iv_base(location, arr.Length(), arr.Elements());
     }
     void Uniform1iv_base(WebGLUniformLocation* location, uint32_t arrayLength,
                          const WebGLint* data);
 
     void Uniform2iv(WebGLUniformLocation* location, dom::Int32Array& arr) {
-        Uniform2iv_base(location, arr.mLength, arr.mData);
+        Uniform2iv_base(location, arr.Length(), arr.Data());
     }
     void Uniform2iv(WebGLUniformLocation* location,
                     const dom::Sequence<WebGLint>& arr) {
         Uniform2iv_base(location, arr.Length(), arr.Elements());
     }
     void Uniform2iv_base(WebGLUniformLocation* location, uint32_t arrayLength,
                          const WebGLint* data);
 
     void Uniform3iv(WebGLUniformLocation* location, dom::Int32Array& arr) {
-        Uniform3iv_base(location, arr.mLength, arr.mData);
+        Uniform3iv_base(location, arr.Length(), arr.Data());
     }
     void Uniform3iv(WebGLUniformLocation* location,
                     const dom::Sequence<WebGLint>& arr) {
         Uniform3iv_base(location, arr.Length(), arr.Elements());
     }
     void Uniform3iv_base(WebGLUniformLocation* location, uint32_t arrayLength,
                          const WebGLint* data);
     
     void Uniform4iv(WebGLUniformLocation* location, dom::Int32Array& arr) {
-        Uniform4iv_base(location, arr.mLength, arr.mData);
+        Uniform4iv_base(location, arr.Length(), arr.Data());
     }
     void Uniform4iv(WebGLUniformLocation* location,
                     const dom::Sequence<WebGLint>& arr) {
         Uniform4iv_base(location, arr.Length(), arr.Elements());
     }
     void Uniform4iv_base(WebGLUniformLocation* location, uint32_t arrayLength,
                          const WebGLint* data);
 
     void Uniform1fv(WebGLUniformLocation* location, dom::Float32Array& arr) {
-        Uniform1fv_base(location, arr.mLength, arr.mData);
+        Uniform1fv_base(location, arr.Length(), arr.Data());
     }
     void Uniform1fv(WebGLUniformLocation* location,
                     const dom::Sequence<WebGLfloat>& arr) {
         Uniform1fv_base(location, arr.Length(), arr.Elements());
     }
     void Uniform1fv_base(WebGLUniformLocation* location, uint32_t arrayLength,
                          const WebGLfloat* data);
 
     void Uniform2fv(WebGLUniformLocation* location, dom::Float32Array& arr) {
-        Uniform2fv_base(location, arr.mLength, arr.mData);
+        Uniform2fv_base(location, arr.Length(), arr.Data());
     }
     void Uniform2fv(WebGLUniformLocation* location,
                     const dom::Sequence<WebGLfloat>& arr) {
         Uniform2fv_base(location, arr.Length(), arr.Elements());
     }
     void Uniform2fv_base(WebGLUniformLocation* location, uint32_t arrayLength,
                          const WebGLfloat* data);
 
     void Uniform3fv(WebGLUniformLocation* location, dom::Float32Array& arr) {
-        Uniform3fv_base(location, arr.mLength, arr.mData);
+        Uniform3fv_base(location, arr.Length(), arr.Data());
     }
     void Uniform3fv(WebGLUniformLocation* location,
                     const dom::Sequence<WebGLfloat>& arr) {
         Uniform3fv_base(location, arr.Length(), arr.Elements());
     }
     void Uniform3fv_base(WebGLUniformLocation* location, uint32_t arrayLength,
                          const WebGLfloat* data);
     
     void Uniform4fv(WebGLUniformLocation* location, dom::Float32Array& arr) {
-        Uniform4fv_base(location, arr.mLength, arr.mData);
+        Uniform4fv_base(location, arr.Length(), arr.Data());
     }
     void Uniform4fv(WebGLUniformLocation* location,
                     const dom::Sequence<WebGLfloat>& arr) {
         Uniform4fv_base(location, arr.Length(), arr.Elements());
     }
     void Uniform4fv_base(WebGLUniformLocation* location, uint32_t arrayLength,
                          const WebGLfloat* data);
 
     void UniformMatrix2fv(WebGLUniformLocation* location,
                           WebGLboolean transpose,
                           dom::Float32Array &value) {
-        UniformMatrix2fv_base(location, transpose, value.mLength, value.mData);
+        UniformMatrix2fv_base(location, transpose, value.Length(), value.Data());
     }
     void UniformMatrix2fv(WebGLUniformLocation* location,
                           WebGLboolean transpose,
                           const dom::Sequence<float> &value) {
         UniformMatrix2fv_base(location, transpose, value.Length(),
                               value.Elements());
     }
     void UniformMatrix2fv_base(WebGLUniformLocation* location,
                                WebGLboolean transpose, uint32_t arrayLength,
                                const float* data);
 
     void UniformMatrix3fv(WebGLUniformLocation* location,
                           WebGLboolean transpose,
                           dom::Float32Array &value) {
-        UniformMatrix3fv_base(location, transpose, value.mLength, value.mData);
+        UniformMatrix3fv_base(location, transpose, value.Length(), value.Data());
     }
     void UniformMatrix3fv(WebGLUniformLocation* location,
                           WebGLboolean transpose,
                           const dom::Sequence<float> &value) {
         UniformMatrix3fv_base(location, transpose, value.Length(),
                               value.Elements());
     }
     void UniformMatrix3fv_base(WebGLUniformLocation* location,
                                WebGLboolean transpose, uint32_t arrayLength,
                                const float* data);
 
     void UniformMatrix4fv(WebGLUniformLocation* location,
                           WebGLboolean transpose,
                           dom::Float32Array &value) {
-        UniformMatrix4fv_base(location, transpose, value.mLength, value.mData);
+        UniformMatrix4fv_base(location, transpose, value.Length(), value.Data());
     }
     void UniformMatrix4fv(WebGLUniformLocation* location,
                           WebGLboolean transpose,
                           const dom::Sequence<float> &value) {
         UniformMatrix4fv_base(location, transpose, value.Length(),
                               value.Elements());
     }
     void UniformMatrix4fv_base(WebGLUniformLocation* location,
@@ -1022,44 +1022,44 @@ public:
     void VertexAttrib1f(WebGLuint index, WebGLfloat x0);
     void VertexAttrib2f(WebGLuint index, WebGLfloat x0, WebGLfloat x1);
     void VertexAttrib3f(WebGLuint index, WebGLfloat x0, WebGLfloat x1,
                         WebGLfloat x2);
     void VertexAttrib4f(WebGLuint index, WebGLfloat x0, WebGLfloat x1,
                         WebGLfloat x2, WebGLfloat x3);
 
     void VertexAttrib1fv(WebGLuint idx, dom::Float32Array &arr) {
-        VertexAttrib1fv_base(idx, arr.mLength, arr.mData);
+        VertexAttrib1fv_base(idx, arr.Length(), arr.Data());
     }
     void VertexAttrib1fv(WebGLuint idx, const dom::Sequence<WebGLfloat>& arr) {
         VertexAttrib1fv_base(idx, arr.Length(), arr.Elements());
     }
     void VertexAttrib1fv_base(WebGLuint idx, uint32_t arrayLength,
                               const WebGLfloat* ptr);
 
     void VertexAttrib2fv(WebGLuint idx, dom::Float32Array &arr) {
-        VertexAttrib2fv_base(idx, arr.mLength, arr.mData);
+        VertexAttrib2fv_base(idx, arr.Length(), arr.Data());
     }
     void VertexAttrib2fv(WebGLuint idx, const dom::Sequence<WebGLfloat>& arr) {
         VertexAttrib2fv_base(idx, arr.Length(), arr.Elements());
     }
     void VertexAttrib2fv_base(WebGLuint idx, uint32_t arrayLength,
                               const WebGLfloat* ptr);
 
     void VertexAttrib3fv(WebGLuint idx, dom::Float32Array &arr) {
-        VertexAttrib3fv_base(idx, arr.mLength, arr.mData);
+        VertexAttrib3fv_base(idx, arr.Length(), arr.Data());
     }
     void VertexAttrib3fv(WebGLuint idx, const dom::Sequence<WebGLfloat>& arr) {
         VertexAttrib3fv_base(idx, arr.Length(), arr.Elements());
     }
     void VertexAttrib3fv_base(WebGLuint idx, uint32_t arrayLength,
                               const WebGLfloat* ptr);
 
     void VertexAttrib4fv(WebGLuint idx, dom::Float32Array &arr) {
-        VertexAttrib4fv_base(idx, arr.mLength, arr.mData);
+        VertexAttrib4fv_base(idx, arr.Length(), arr.Data());
     }
     void VertexAttrib4fv(WebGLuint idx, const dom::Sequence<WebGLfloat>& arr) {
         VertexAttrib4fv_base(idx, arr.Length(), arr.Elements());
     }
     void VertexAttrib4fv_base(WebGLuint idx, uint32_t arrayLength,
                               const WebGLfloat* ptr);
     
     void VertexAttribPointer(WebGLuint index, WebGLint size, WebGLenum type,
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -541,26 +541,26 @@ WebGLContext::BufferData(WebGLenum targe
     if (!ValidateBufferUsageEnum(usage, "bufferData: usage"))
         return;
 
     if (!boundBuffer)
         return ErrorInvalidOperation("bufferData: no buffer bound!");
 
     MakeContextCurrent();
 
-    GLenum error = CheckedBufferData(target, data->mLength, data->mData, usage);
+    GLenum error = CheckedBufferData(target, data->Length(), data->Data(), usage);
 
     if (error) {
         GenerateWarning("bufferData generated error %s", ErrorName(error));
         return;
     }
 
-    boundBuffer->SetByteLength(data->mLength);
+    boundBuffer->SetByteLength(data->Length());
     boundBuffer->InvalidateCachedMaxElements();
-    if (!boundBuffer->CopyDataIfElementArray(data->mData))
+    if (!boundBuffer->CopyDataIfElementArray(data->Data()))
         return ErrorOutOfMemory("bufferData: out of memory");
 }
 
 void
 WebGLContext::BufferData(WebGLenum target, ArrayBufferView& data, WebGLenum usage)
 {
     if (!IsContextStable())
         return;
@@ -578,25 +578,25 @@ WebGLContext::BufferData(WebGLenum targe
     if (!ValidateBufferUsageEnum(usage, "bufferData: usage"))
         return;
 
     if (!boundBuffer)
         return ErrorInvalidOperation("bufferData: no buffer bound!");
 
     MakeContextCurrent();
 
-    GLenum error = CheckedBufferData(target, data.mLength, data.mData, usage);
+    GLenum error = CheckedBufferData(target, data.Length(), data.Data(), usage);
     if (error) {
         GenerateWarning("bufferData generated error %s", ErrorName(error));
         return;
     }
 
-    boundBuffer->SetByteLength(data.mLength);
+    boundBuffer->SetByteLength(data.Length());
     boundBuffer->InvalidateCachedMaxElements();
-    if (!boundBuffer->CopyDataIfElementArray(data.mData))
+    if (!boundBuffer->CopyDataIfElementArray(data.Data()))
         return ErrorOutOfMemory("bufferData: out of memory");
 }
 
 NS_IMETHODIMP
 WebGLContext::BufferSubData(WebGLenum target, WebGLintptr offset, const JS::Value& data, JSContext *cx)
 {
     if (!IsContextStable())
         return NS_OK;
@@ -649,30 +649,30 @@ WebGLContext::BufferSubData(GLenum targe
     }
 
     if (byteOffset < 0)
         return ErrorInvalidValue("bufferSubData: negative offset");
 
     if (!boundBuffer)
         return ErrorInvalidOperation("bufferData: no buffer bound!");
 
-    CheckedUint32 checked_neededByteLength = CheckedUint32(byteOffset) + data->mLength;
+    CheckedUint32 checked_neededByteLength = CheckedUint32(byteOffset) + data->Length();
     if (!checked_neededByteLength.isValid())
         return ErrorInvalidOperation("bufferSubData: integer overflow computing the needed byte length");
 
     if (checked_neededByteLength.value() > boundBuffer->ByteLength())
         return ErrorInvalidOperation("bufferSubData: not enough data - operation requires %d bytes, but buffer only has %d bytes",
                                      checked_neededByteLength.value(), boundBuffer->ByteLength());
 
     MakeContextCurrent();
 
-    boundBuffer->CopySubDataIfElementArray(byteOffset, data->mLength, data->mData);
+    boundBuffer->CopySubDataIfElementArray(byteOffset, data->Length(), data->Data());
     boundBuffer->InvalidateCachedMaxElements();
 
-    gl->fBufferSubData(target, byteOffset, data->mLength, data->mData);
+    gl->fBufferSubData(target, byteOffset, data->Length(), data->Data());
 }
 
 void
 WebGLContext::BufferSubData(WebGLenum target, WebGLsizeiptr byteOffset,
                             ArrayBufferView& data)
 {
     if (!IsContextStable())
         return;
@@ -688,30 +688,30 @@ WebGLContext::BufferSubData(WebGLenum ta
     }
 
     if (byteOffset < 0)
         return ErrorInvalidValue("bufferSubData: negative offset");
 
     if (!boundBuffer)
         return ErrorInvalidOperation("bufferSubData: no buffer bound!");
 
-    CheckedUint32 checked_neededByteLength = CheckedUint32(byteOffset) + data.mLength;
+    CheckedUint32 checked_neededByteLength = CheckedUint32(byteOffset) + data.Length();
     if (!checked_neededByteLength.isValid())
         return ErrorInvalidOperation("bufferSubData: integer overflow computing the needed byte length");
 
     if (checked_neededByteLength.value() > boundBuffer->ByteLength())
         return ErrorInvalidOperation("bufferSubData: not enough data -- operation requires %d bytes, but buffer only has %d bytes",
                                      checked_neededByteLength.value(), boundBuffer->ByteLength());
 
     MakeContextCurrent();
 
-    boundBuffer->CopySubDataIfElementArray(byteOffset, data.mLength, data.mData);
+    boundBuffer->CopySubDataIfElementArray(byteOffset, data.Length(), data.Data());
     boundBuffer->InvalidateCachedMaxElements();
 
-    gl->fBufferSubData(target, byteOffset, data.mLength, data.mData);
+    gl->fBufferSubData(target, byteOffset, data.Length(), data.Data());
 }
 
 NS_IMETHODIMP
 WebGLContext::CheckFramebufferStatus(WebGLenum target, WebGLenum *retval)
 {
     *retval = CheckFramebufferStatus(target);
     return NS_OK;
 }
@@ -3871,19 +3871,19 @@ 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->mData;
-    uint32_t dataByteLen = JS_GetTypedArrayByteLength(pixels->mObj, NULL);
-    int dataType = JS_GetTypedArrayType(pixels->mObj, NULL);
+    void* data = pixels->Data();
+    uint32_t dataByteLen = JS_GetTypedArrayByteLength(pixels->Obj(), NULL);
+    int dataType = JS_GetTypedArrayType(pixels->Obj(), NULL);
 
     uint32_t channels = 0;
 
     // Check the format param
     switch (format) {
         case LOCAL_GL_ALPHA:
             channels = 1;
             break;
@@ -5141,22 +5141,22 @@ WebGLContext::CompressedTexImage2D(WebGL
         return;
     }
 
     if (border) {
         ErrorInvalidValue("compressedTexImage2D: border is not 0");
         return;
     }
 
-    uint32_t byteLength = view.mLength;
+    uint32_t byteLength = view.Length();
     if (!ValidateCompressedTextureSize(level, internalformat, width, height, byteLength, "compressedTexImage2D")) {
         return;
     }
 
-    gl->fCompressedTexImage2D(target, level, internalformat, width, height, border, byteLength, view.mData);
+    gl->fCompressedTexImage2D(target, level, internalformat, width, height, border, byteLength, view.Data());
     tex->SetImageInfo(target, level, width, height, internalformat, LOCAL_GL_UNSIGNED_BYTE);
 }
 
 NS_IMETHODIMP
 WebGLContext::CompressedTexSubImage2D(WebGLenum target, WebGLint level, WebGLint xoffset,
                                       WebGLint yoffset, WebGLsizei width, WebGLsizei height,
                                       WebGLenum format, const JS::Value& pixels, JSContext *cx)
 {
@@ -5202,17 +5202,17 @@ WebGLContext::CompressedTexSubImage2D(We
         ErrorInvalidEnum("compressedTexSubImage2D: compressed texture format 0x%x is not supported", format);
         return;
     }
 
     if (!ValidateLevelWidthHeightForTarget(target, level, width, height, "compressedTexSubImage2D")) {
         return;
     }
 
-    uint32_t byteLength = view.mLength;
+    uint32_t byteLength = view.Length();
     if (!ValidateCompressedTextureSize(level, format, width, height, byteLength, "compressedTexSubImage2D")) {
         return;
     }
 
     size_t face = WebGLTexture::FaceForTarget(target);
 
     if (!tex->HasImageInfoAt(level, face)) {
         ErrorInvalidOperation("compressedTexSubImage2D: no texture image previously defined for this level and face");
@@ -5247,17 +5247,17 @@ WebGLContext::CompressedTexSubImage2D(We
             if (height % 4 != 0 && height != imageInfo.Height()) {
                 ErrorInvalidOperation("compressedTexSubImage2D: height is not a multiple of 4 or equal to texture height");
                 return;
             }
             break;
         }
     }
 
-    gl->fCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, byteLength, view.mData);
+    gl->fCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, byteLength, view.Data());
 
     return;
 }
 
 NS_IMETHODIMP
 WebGLContext::GetShaderParameter(nsIWebGLShader *sobj, WebGLenum pname, JS::Value *retval)
 {
     *retval = GetShaderParameter(static_cast<WebGLShader*>(sobj), pname);
@@ -5737,19 +5737,19 @@ WebGLContext::TexImage2D(JSContext* cx, 
                          WebGLenum internalformat, WebGLsizei width,
                          WebGLsizei height, WebGLint border, WebGLenum format,
                          WebGLenum type, ArrayBufferView *pixels, ErrorResult& rv)
 {
     if (!IsContextStable())
         return;
 
     return TexImage2D_base(target, level, internalformat, width, height, 0, border, format, type,
-                           pixels ? pixels->mData : 0,
-                           pixels ? pixels->mLength : 0,
-                           pixels ? (int)JS_GetTypedArrayType(pixels->mObj, cx) : -1,
+                           pixels ? pixels->Data() : 0,
+                           pixels ? pixels->Length() : 0,
+                           pixels ? (int)JS_GetTypedArrayType(pixels->Obj(), cx) : -1,
                            WebGLTexelConversions::Auto, false);
 }
 
 NS_IMETHODIMP
 WebGLContext::TexImage2D_imageData(WebGLenum target, WebGLint level, WebGLenum internalformat,
                                    WebGLsizei width, WebGLsizei height, WebGLint border,
                                    WebGLenum format, WebGLenum type,
                                    JSObject *pixels, JSContext *cx)
@@ -5778,17 +5778,17 @@ WebGLContext::TexImage2D(JSContext* cx, 
     if (!pixels) {
         // Spec says to generate an INVALID_VALUE error
         return ErrorInvalidValue("texImage2D: null ImageData");
     }
     
     Uint8ClampedArray arr(cx, pixels->GetDataObject());
     return TexImage2D_base(target, level, internalformat, pixels->GetWidth(),
                            pixels->GetHeight(), 4*pixels->GetWidth(), 0,
-                           format, type, arr.mData, arr.mLength, -1,
+                           format, type, arr.Data(), arr.Length(), -1,
                            WebGLTexelConversions::RGBA8, false);
 }
 
 
 NS_IMETHODIMP
 WebGLContext::TexImage2D_dom(WebGLenum target, WebGLint level, WebGLenum internalformat,
                              WebGLenum format, GLenum type, Element* elt)
 {
@@ -5943,18 +5943,18 @@ WebGLContext::TexSubImage2D(JSContext* c
     if (!IsContextStable())
         return;
 
     if (!pixels)
         return ErrorInvalidValue("texSubImage2D: pixels must not be null!");
 
     return TexSubImage2D_base(target, level, xoffset, yoffset,
                               width, height, 0, format, type,
-                              pixels->mData, pixels->mLength,
-                              JS_GetTypedArrayType(pixels->mObj, cx),
+                              pixels->Data(), pixels->Length(),
+                              JS_GetTypedArrayType(pixels->Obj(), cx),
                               WebGLTexelConversions::Auto, false);
 }
 
 NS_IMETHODIMP
 WebGLContext::TexSubImage2D_imageData(WebGLenum target, WebGLint level,
                                       WebGLint xoffset, WebGLint yoffset,
                                       WebGLsizei width, WebGLsizei height,
                                       WebGLenum format, WebGLenum type,
@@ -5989,17 +5989,17 @@ WebGLContext::TexSubImage2D(JSContext* c
 
     if (!pixels)
         return ErrorInvalidValue("texSubImage2D: pixels must not be null!");
 
     Uint8ClampedArray arr(cx, pixels->GetDataObject());
     return TexSubImage2D_base(target, level, xoffset, yoffset,
                               pixels->GetWidth(), pixels->GetHeight(),
                               4*pixels->GetWidth(), format, type,
-                              arr.mData, arr.mLength,
+                              arr.Data(), arr.Length(),
                               -1,
                               WebGLTexelConversions::RGBA8, false);
 }
 
 NS_IMETHODIMP
 WebGLContext::TexSubImage2D_dom(WebGLenum target, WebGLint level,
                                 WebGLint xoffset, WebGLint yoffset,
                                 WebGLenum format, WebGLenum type,
--- a/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
@@ -4347,17 +4347,17 @@ nsCanvasRenderingContext2DAzure::PutImag
     error.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
     return;
   }
 
   dom::Uint8ClampedArray arr(cx, imageData->GetDataObject());
 
   error = PutImageData_explicit(JS_DoubleToInt32(dx), JS_DoubleToInt32(dy),
                                 imageData->GetWidth(), imageData->GetHeight(),
-                                arr.mData, arr.mLength, false, 0, 0, 0, 0);
+                                arr.Data(), arr.Length(), false, 0, 0, 0, 0);
 }
 
 void
 nsCanvasRenderingContext2DAzure::PutImageData(JSContext* cx,
                                               ImageData* imageData, double dx,
                                               double dy, double dirtyX,
                                               double dirtyY, double dirtyWidth,
                                               double dirtyHeight,
@@ -4367,17 +4367,17 @@ nsCanvasRenderingContext2DAzure::PutImag
     error.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
     return;
   }
 
   dom::Uint8ClampedArray arr(cx, imageData->GetDataObject());
 
   error = PutImageData_explicit(JS_DoubleToInt32(dx), JS_DoubleToInt32(dy),
                                 imageData->GetWidth(), imageData->GetHeight(),
-                                arr.mData, arr.mLength, true,
+                                arr.Data(), arr.Length(), true,
                                 JS_DoubleToInt32(dirtyX),
                                 JS_DoubleToInt32(dirtyY),
                                 JS_DoubleToInt32(dirtyWidth),
                                 JS_DoubleToInt32(dirtyHeight));
 }
 
 // void putImageData (in ImageData d, in float x, in float y);
 // void putImageData (in ImageData d, in double x, in double y, in double dirtyX, in double dirtyY, in double dirtyWidth, in double dirtyHeight);
--- a/dom/bindings/TypedArray.h
+++ b/dom/bindings/TypedArray.h
@@ -13,41 +13,60 @@ namespace mozilla {
 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, typename U,
-         U* GetData(JSObject*, JSContext*),
-         uint32_t GetLength(JSObject*, JSContext*)>
+template<typename T,
+         JSObject* UnboxArray(JSContext*, JSObject*, uint32_t*, T**)>
 struct TypedArray_base {
-  TypedArray_base(JSContext* cx, JSObject* obj) :
-    mData(static_cast<T*>(GetData(obj, cx))),
-    mLength(GetLength(obj, cx)),
-    mObj(obj)
-  {}
+  TypedArray_base(JSContext* cx, JSObject* obj)
+  {
+    mObj = UnboxArray(cx, obj, &mLength, &mData);
+  }
+
+private:
+  T* mData;
+  uint32_t mLength;
+  JSObject* mObj;
+
+public:
+  inline bool inited() const {
+    return !!mObj;
+  }
 
-  T* const mData;
-  const uint32_t mLength;
-  JSObject* const mObj;
+  inline T *Data() const {
+    MOZ_ASSERT(inited());
+    return mData;
+  }
+
+  inline uint32_t Length() const {
+    MOZ_ASSERT(inited());
+    return mLength;
+  }
+
+  inline JSObject *Obj() const {
+    MOZ_ASSERT(inited());
+    return mObj;
+  }
 };
 
 
-template<typename T, typename U,
-         U* GetData(JSObject*, JSContext*),
-         uint32_t GetLength(JSObject*, JSContext*),
+template<typename T,
+         T* GetData(JSObject*, JSContext*),
+         JSObject* UnboxArray(JSContext*, JSObject*, uint32_t*, T**),
          JSObject* CreateNew(JSContext*, uint32_t)>
-struct TypedArray : public TypedArray_base<T,U,GetData,GetLength> {
+struct TypedArray : public TypedArray_base<T,UnboxArray> {
   TypedArray(JSContext* cx, JSObject* obj) :
-    TypedArray_base<T,U,GetData,GetLength>(cx, obj)
+    TypedArray_base<T,UnboxArray>(cx, obj)
   {}
-  
+
   static inline JSObject*
   Create(JSContext* cx, nsWrapperCache* creator, uint32_t length,
          T* data = NULL) {
     JSObject* creatorWrapper;
     JSAutoEnterCompartment ac;
     if (creator && (creatorWrapper = creator->GetWrapperPreserveColor())) {
       if (!ac.enter(cx, creatorWrapper)) {
         return NULL;
@@ -60,46 +79,45 @@ struct TypedArray : public TypedArray_ba
     if (data) {
       T* buf = static_cast<T*>(GetData(obj, cx));
       memcpy(buf, data, length*sizeof(T));
     }
     return obj;
   }
 };
 
-typedef TypedArray<int8_t, int8_t, JS_GetInt8ArrayData, JS_GetTypedArrayLength,
+typedef TypedArray<int8_t, JS_GetInt8ArrayData, JS_GetObjectAsInt8Array,
                    JS_NewInt8Array>
         Int8Array;
-typedef TypedArray<uint8_t, uint8_t, JS_GetUint8ArrayData,
-                   JS_GetTypedArrayLength, JS_NewUint8Array>
+typedef TypedArray<uint8_t, JS_GetUint8ArrayData,
+                   JS_GetObjectAsUint8Array, JS_NewUint8Array>
         Uint8Array;
-typedef TypedArray<uint8_t, uint8_t, JS_GetUint8ClampedArrayData,
-                   JS_GetTypedArrayLength, JS_NewUint8ClampedArray>
+typedef TypedArray<uint8_t, JS_GetUint8ClampedArrayData,
+                   JS_GetObjectAsUint8ClampedArray, JS_NewUint8ClampedArray>
         Uint8ClampedArray;
-typedef TypedArray<int16_t, int16_t, JS_GetInt16ArrayData,
-                   JS_GetTypedArrayLength, JS_NewInt16Array>
+typedef TypedArray<int16_t, JS_GetInt16ArrayData,
+                   JS_GetObjectAsInt16Array, JS_NewInt16Array>
         Int16Array;
-typedef TypedArray<uint16_t, uint16_t, JS_GetUint16ArrayData,
-                   JS_GetTypedArrayLength, JS_NewUint16Array>
+typedef TypedArray<uint16_t, JS_GetUint16ArrayData,
+                   JS_GetObjectAsUint16Array, JS_NewUint16Array>
         Uint16Array;
-typedef TypedArray<int32_t, int32_t, JS_GetInt32ArrayData,
-                   JS_GetTypedArrayLength, JS_NewInt32Array>
+typedef TypedArray<int32_t, JS_GetInt32ArrayData,
+                   JS_GetObjectAsInt32Array, JS_NewInt32Array>
         Int32Array;
-typedef TypedArray<uint32_t, uint32_t, JS_GetUint32ArrayData,
-                   JS_GetTypedArrayLength, JS_NewUint32Array>
+typedef TypedArray<uint32_t, JS_GetUint32ArrayData,
+                   JS_GetObjectAsUint32Array, JS_NewUint32Array>
         Uint32Array;
-typedef TypedArray<float, float, JS_GetFloat32ArrayData, JS_GetTypedArrayLength,
-                   JS_NewFloat32Array>
+typedef TypedArray<float, JS_GetFloat32ArrayData,
+                   JS_GetObjectAsFloat32Array, JS_NewFloat32Array>
         Float32Array;
-typedef TypedArray<double, double, JS_GetFloat64ArrayData,
-                   JS_GetTypedArrayLength, JS_NewFloat64Array>
+typedef TypedArray<double, JS_GetFloat64ArrayData,
+                   JS_GetObjectAsFloat64Array, JS_NewFloat64Array>
         Float64Array;
-typedef TypedArray_base<uint8_t, void, JS_GetArrayBufferViewData,
-                        JS_GetArrayBufferViewByteLength>
+typedef TypedArray_base<uint8_t, JS_GetObjectAsArrayBufferView>
         ArrayBufferView;
-typedef TypedArray<uint8_t, uint8_t, JS_GetArrayBufferData,
-                   JS_GetArrayBufferByteLength, JS_NewArrayBuffer>
+typedef TypedArray<uint8_t, JS_GetArrayBufferData,
+                   JS_GetObjectAsArrayBuffer, JS_NewArrayBuffer>
         ArrayBuffer;
 
 } // namespace dom
 } // namespace mozilla
 
 #endif /* mozilla_dom_TypedArray_h */
--- a/dom/workers/XMLHttpRequest.h
+++ b/dom/workers/XMLHttpRequest.h
@@ -157,17 +157,17 @@ public:
   void
   Send(const nsAString& aBody, ErrorResult& aRv);
 
   void
   Send(JSObject* aBody, ErrorResult& aRv);
 
   void
   Send(ArrayBuffer& aBody, ErrorResult& aRv) {
-    return Send(aBody.mObj, aRv);
+    return Send(aBody.Obj(), aRv);
   }
 
   void
   SendAsBinary(const nsAString& aBody, ErrorResult& aRv);
 
   void
   Abort(ErrorResult& aRv);