Bug 748266. Switch the WebGL canvas context to new DOM bindings. r=peterv
☠☠ backed out by 9375a7ac5a90 ☠ ☠
authorBoris Zbarsky <bzbarsky@mit.edu>
Thu, 31 May 2012 14:16:48 -0400
changeset 99469 f96e0f078b49e1e7a1be42c41990a10107ee5b91
parent 99468 359f1096bc7cb983ebd59144ba6955160937bc9e
child 99470 6a46906eb017e456553d92506456489b3f745252
child 99480 9375a7ac5a909ea6a742afaf35ed3df5de17b137
push id1116
push userlsblakk@mozilla.com
push dateMon, 16 Jul 2012 19:38:18 +0000
treeherdermozilla-beta@95f959a8b4dc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspeterv
bugs748266
milestone15.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 748266. Switch the WebGL canvas context to new DOM bindings. r=peterv
content/base/src/nsXMLHttpRequest.cpp
content/base/src/nsXMLHttpRequest.h
content/canvas/src/WebGLContext.cpp
content/canvas/src/WebGLContext.h
content/canvas/src/WebGLContextGL.cpp
content/html/content/public/nsHTMLCanvasElement.h
content/html/content/src/nsHTMLImageElement.cpp
content/html/content/src/nsHTMLImageElement.h
dom/base/nsDOMClassInfoID.h
dom/bindings/Bindings.conf
dom/bindings/Codegen.py
dom/bindings/Makefile.in
dom/bindings/test/TestBindingHeader.h
dom/webidl/WebGLRenderingContext.webidl
dom/webidl/WebIDL.mk
dom/workers/XMLHttpRequest.cpp
dom/workers/XMLHttpRequest.h
dom/workers/XMLHttpRequestEventTarget.h
js/xpconnect/src/nsDOMQS.h
js/xpconnect/src/qsWinUndefs.h
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -2611,17 +2611,17 @@ GetRequestBody(nsIInputStream* aStream, 
 static nsresult
 GetRequestBody(nsIXHRSendable* aSendable, nsIInputStream** aResult,
                nsACString& aContentType, nsACString& aCharset)
 {
   return aSendable->GetSendInfo(aResult, aContentType, aCharset);
 }
 
 static nsresult
-GetRequestBody(ArrayBuffer* aArrayBuffer, JSContext *aCx, nsIInputStream** aResult,
+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);
 
@@ -2684,17 +2684,17 @@ GetRequestBody(nsIVariant* aBody, JSCont
     // ArrayBuffer?
     jsval realVal;
     JSObject* obj;
     nsresult rv = aBody->GetAsJSVal(&realVal);
     if (NS_SUCCEEDED(rv) && !JSVAL_IS_PRIMITIVE(realVal) &&
         (obj = JSVAL_TO_OBJECT(realVal)) &&
         (JS_IsArrayBufferObject(obj, aCx))) {
       ArrayBuffer buf(aCx, obj);
-      return GetRequestBody(&buf, aCx, aResult, aContentType, aCharset);
+      return GetRequestBody(&buf, aResult, 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");
     aCharset.AssignLiteral("UTF-8");
 
@@ -2723,17 +2723,17 @@ nsXMLHttpRequest::GetRequestBody(nsIVari
     return ::GetRequestBody(aVariant, aCx, aResult, aContentType, aCharset);
   }
 
   const RequestBody& body = aBody.Value();
   RequestBody::Value value = body.GetValue();
   switch (body.GetType()) {
     case nsXMLHttpRequest::RequestBody::ArrayBuffer:
     {
-      return ::GetRequestBody(value.mArrayBuffer, aCx, aResult, aContentType, aCharset);
+      return ::GetRequestBody(value.mArrayBuffer, aResult, aContentType, aCharset);
     }
     case nsXMLHttpRequest::RequestBody::Blob:
     {
       nsresult rv;
       nsCOMPtr<nsIXHRSendable> sendable = do_QueryInterface(value.mBlob, &rv);
       NS_ENSURE_SUCCESS(rv, rv);
 
       return ::GetRequestBody(sendable, aResult, aContentType, aCharset);
--- a/content/base/src/nsXMLHttpRequest.h
+++ b/content/base/src/nsXMLHttpRequest.h
@@ -44,17 +44,17 @@
 #include "mozilla/dom/TypedArray.h"
 
 class nsILoadGroup;
 class AsyncVerifyRedirectCallbackForwarder;
 class nsIUnicodeDecoder;
 class nsIDOMFormData;
 
 #define IMPL_EVENT_HANDLER(_lowercase, _capitalized)                    \
-  JSObject* GetOn##_lowercase()                                         \
+  JSObject* GetOn##_lowercase(JSContext* /* unused */ )                 \
   {                                                                     \
     return GetListenerAsJSObject(mOn##_capitalized##Listener);          \
   }                                                                     \
   void SetOn##_lowercase(JSContext* aCx, JSObject* aCallback, ErrorResult& aRv) \
   {                                                                     \
     aRv = SetJSObjectListener(aCx, NS_LITERAL_STRING(#_lowercase),      \
                               mOn##_capitalized##Listener,              \
                               aCallback);                               \
@@ -342,16 +342,18 @@ private:
 
   static nsresult GetRequestBody(nsIVariant* aVariant,
                                  JSContext* aCx,
                                  const Nullable<RequestBody>& aBody,
                                  nsIInputStream** aResult,
                                  nsACString& aContentType,
                                  nsACString& aCharset);
 
+  // XXXbz once the nsIVariant bits here go away, we can remove the
+  // implicitJSContext bits in Bindings.conf.
   nsresult Send(JSContext *aCx, nsIVariant* aVariant, const Nullable<RequestBody>& aBody);
   nsresult Send(JSContext *aCx, const Nullable<RequestBody>& aBody)
   {
     return Send(aCx, nsnull, aBody);
   }
   nsresult Send(JSContext *aCx, const RequestBody& aBody)
   {
     return Send(aCx, Nullable<RequestBody>(aBody));
--- a/content/canvas/src/WebGLContext.cpp
+++ b/content/canvas/src/WebGLContext.cpp
@@ -33,17 +33,17 @@
 #include "nsSVGEffects.h"
 
 #include "prenv.h"
 
 #include "mozilla/Preferences.h"
 #include "mozilla/Telemetry.h"
 
 #include "nsIObserverService.h"
-
+#include "mozilla/dom/WebGLRenderingContextBinding.h"
 
 using namespace mozilla;
 using namespace mozilla::gl;
 using namespace mozilla::layers;
 
 NS_IMPL_ISUPPORTS1(WebGLMemoryPressureObserver, nsIObserver)
 
 NS_IMETHODIMP
@@ -70,16 +70,17 @@ NS_NewCanvasRenderingContextWebGL(nsIDOM
     NS_ADDREF(*aResult = ctx);
     return NS_OK;
 }
 
 WebGLContext::WebGLContext()
     : mCanvasElement(nsnull),
       gl(nsnull)
 {
+    SetIsDOMBinding();
     mEnabledExtensions.SetLength(WebGLExtensionID_Max);
 
     mGeneration = 0;
     mInvalidated = false;
     mResetLayer = true;
     mOptionsFrozen = false;
 
     mActiveTexture = 0;
@@ -159,16 +160,24 @@ WebGLContext::WebGLContext()
 WebGLContext::~WebGLContext()
 {
     DestroyResourcesAndContext();
     WebGLMemoryMultiReporterWrapper::RemoveWebGLContext(this);
     TerminateContextLossTimer();
     mContextRestorer = nsnull;
 }
 
+JSObject*
+WebGLContext::WrapObject(JSContext *cx, JSObject *scope,
+                         bool *triedToWrap)
+{
+    return dom::WebGLRenderingContextBinding::Wrap(cx, scope, this,
+                                                   triedToWrap);
+}
+
 void
 WebGLContext::DestroyResourcesAndContext()
 {
     if (mMemoryPressureObserver) {
         nsCOMPtr<nsIObserverService> observerService
             = mozilla::services::GetObserverService();
         if (observerService) {
             observerService->RemoveObserver(mMemoryPressureObserver,
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -481,16 +481,19 @@ public:
 
     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(WebGLContext,
                                                            nsIDOMWebGLRenderingContext)
 
     nsINode* GetParentObject() {
         return HTMLCanvasElement();
     }
 
+    virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
+                                 bool *triedToWrap);
+
     NS_DECL_NSIDOMWEBGLRENDERINGCONTEXT
 
     NS_DECL_NSITIMERCALLBACK
 
     // nsICanvasRenderingContextInternal
     NS_IMETHOD SetCanvasElement(nsHTMLCanvasElement* aParentCanvas);
     nsHTMLCanvasElement* HTMLCanvasElement() const {
         return static_cast<nsHTMLCanvasElement*>(mCanvasElement.get());
@@ -727,34 +730,54 @@ public:
     already_AddRefed<WebGLActiveInfo> GetActiveAttrib(WebGLProgram *prog,
                                                       WebGLuint index);
     already_AddRefed<WebGLActiveInfo> GetActiveUniform(WebGLProgram *prog,
                                                        WebGLuint index);
     void GetAttachedShaders(WebGLProgram* prog,
                             dom::Nullable< nsTArray<WebGLShader*> > &retval);
     WebGLint GetAttribLocation(WebGLProgram* prog, const nsAString& name);
     JS::Value GetBufferParameter(WebGLenum target, WebGLenum pname);
+    JS::Value GetBufferParameter(JSContext* /* unused */, WebGLenum target,
+                                 WebGLenum pname) {
+        return GetBufferParameter(target, pname);
+    }
     JS::Value GetParameter(JSContext* cx, WebGLenum pname, ErrorResult& rv);
     WebGLenum GetError();
     JS::Value GetFramebufferAttachmentParameter(JSContext* cx,
                                                 WebGLenum target,
                                                 WebGLenum attachment,
                                                 WebGLenum pname,
                                                 ErrorResult& rv);
     JS::Value GetProgramParameter(WebGLProgram *prog, WebGLenum pname);
+    JS::Value GetProgramParameter(JSContext* /* unused */, WebGLProgram *prog,
+                                  WebGLenum pname) {
+        return GetProgramParameter(prog, pname);
+    }
     void GetProgramInfoLog(WebGLProgram *prog, nsACString& retval, ErrorResult& rv);
     void GetProgramInfoLog(WebGLProgram *prog, nsAString& retval, ErrorResult& rv);
     JS::Value GetRenderbufferParameter(WebGLenum target, WebGLenum pname);
+    JS::Value GetRenderbufferParameter(JSContext* /* unused */,
+                                       WebGLenum target, WebGLenum pname) {
+        return GetRenderbufferParameter(target, pname);
+    }
     JS::Value GetShaderParameter(WebGLShader *shader, WebGLenum pname);
+    JS::Value GetShaderParameter(JSContext* /* unused */, WebGLShader *shader,
+                                 WebGLenum pname) {
+        return GetShaderParameter(shader, pname);
+    }
     already_AddRefed<WebGLShaderPrecisionFormat>
       GetShaderPrecisionFormat(WebGLenum shadertype, WebGLenum precisiontype);
     void GetShaderInfoLog(WebGLShader *shader, nsACString& retval, ErrorResult& rv);
     void GetShaderInfoLog(WebGLShader *shader, nsAString& retval, ErrorResult& rv);
     void GetShaderSource(WebGLShader *shader, nsAString& retval);
     JS::Value GetTexParameter(WebGLenum target, WebGLenum pname);
+    JS::Value GetTexParameter(JSContext * /* unused */, WebGLenum target,
+                              WebGLenum pname) {
+        return GetTexParameter(target, pname);
+    }
     JS::Value GetUniform(JSContext* cx, WebGLProgram *prog,
                          WebGLUniformLocation *location, ErrorResult& rv);
     already_AddRefed<WebGLUniformLocation>
       GetUniformLocation(WebGLProgram *prog, const nsAString& name);
     JS::Value GetVertexAttrib(JSContext* cx, WebGLuint index, WebGLenum pname,
                               ErrorResult& rv);
     WebGLsizeiptr GetVertexAttribOffset(WebGLuint index, WebGLenum pname);
     void Hint(WebGLenum target, WebGLenum mode);
@@ -803,37 +826,77 @@ public:
     void TexImage2D(JSContext* cx, WebGLenum target, WebGLint level,
                     WebGLenum internalformat, WebGLsizei width,
                     WebGLsizei height, WebGLint border, WebGLenum format,
                     WebGLenum type, dom::ArrayBufferView *pixels,
                     ErrorResult& rv);
     void TexImage2D(JSContext* cx, WebGLenum target, WebGLint level,
                     WebGLenum internalformat, WebGLenum format, WebGLenum type,
                     dom::ImageData* pixels, ErrorResult& rv);
+    // Allow whatever element types the bindings are willing to pass
+    // us in TexImage2D
+    template<class ElementType>
     void TexImage2D(JSContext* /* unused */, WebGLenum target, WebGLint level,
                     WebGLenum internalformat, WebGLenum format, WebGLenum type,
-                    dom::Element* elt, ErrorResult& rv);
+                    ElementType* elt, ErrorResult& rv) {
+        if (!IsContextStable())
+            return;
+        nsRefPtr<gfxImageSurface> isurf;
+        WebGLTexelFormat srcFormat;
+        nsLayoutUtils::SurfaceFromElementResult res = SurfaceFromElement(elt);
+        rv = SurfaceFromElementResultToImageSurface(res, getter_AddRefs(isurf),
+                                                    &srcFormat);
+        if (rv.Failed())
+            return;
+
+        uint32_t byteLength = isurf->Stride() * isurf->Height();
+        return TexImage2D_base(target, level, internalformat,
+                               isurf->Width(), isurf->Height(), isurf->Stride(),
+                               0, format, type, isurf->Data(), byteLength,
+                               -1, srcFormat, mPixelStorePremultiplyAlpha);
+    }
     void TexParameterf(WebGLenum target, WebGLenum pname, WebGLfloat param) {
         TexParameter_base(target, pname, nsnull, &param);
     }
     void TexParameteri(WebGLenum target, WebGLenum pname, WebGLint param) {
         TexParameter_base(target, pname, &param, nsnull);
     }
     
     void TexSubImage2D(JSContext* cx, WebGLenum target, WebGLint level,
                        WebGLint xoffset, WebGLint yoffset,
                        WebGLsizei width, WebGLsizei height, WebGLenum format,
                        WebGLenum type, dom::ArrayBufferView* pixels,
                        ErrorResult& rv);
     void TexSubImage2D(JSContext* cx, WebGLenum target, WebGLint level,
                        WebGLint xoffset, WebGLint yoffset, WebGLenum format,
                        WebGLenum type, dom::ImageData* pixels, ErrorResult& rv);
+    // Allow whatever element types the bindings are willing to pass
+    // us in TexSubImage2D
+    template<class ElementType>
     void TexSubImage2D(JSContext* /* unused */, WebGLenum target, WebGLint level,
                        WebGLint xoffset, WebGLint yoffset, WebGLenum format,
-                       WebGLenum type, dom::Element* elt, ErrorResult& rv);
+                       WebGLenum type, ElementType* elt, ErrorResult& rv) {
+        if (!IsContextStable())
+            return;
+        nsRefPtr<gfxImageSurface> isurf;
+        WebGLTexelFormat srcFormat;
+        nsLayoutUtils::SurfaceFromElementResult res = SurfaceFromElement(elt);
+        rv = SurfaceFromElementResultToImageSurface(res, getter_AddRefs(isurf),
+                                                    &srcFormat);
+        if (rv.Failed())
+            return;
+
+        uint32_t byteLength = isurf->Stride() * isurf->Height();
+        return TexSubImage2D_base(target, level, xoffset, yoffset,
+                                  isurf->Width(), isurf->Height(),
+                                  isurf->Stride(), format, type,
+                                  isurf->Data(), byteLength,
+                                  -1, srcFormat, mPixelStorePremultiplyAlpha);
+        
+    }
 
     void Uniform1i(WebGLUniformLocation* location, WebGLint x);
     void Uniform2i(WebGLUniformLocation* location, WebGLint x, WebGLint y);
     void Uniform3i(WebGLUniformLocation* location, WebGLint x, WebGLint y,
                    WebGLint z);
     void Uniform4i(WebGLUniformLocation* location, WebGLint x, WebGLint y,
                    WebGLint z, WebGLint w);
 
@@ -1167,19 +1230,33 @@ protected:
                            WebGLint *intParamPtr, WebGLfloat *floatParamPtr);
 
     void ConvertImage(size_t width, size_t height, size_t srcStride, size_t dstStride,
                       const uint8_t* src, uint8_t *dst,
                       WebGLTexelFormat srcFormat, bool srcPremultiplied,
                       WebGLTexelFormat dstFormat, bool dstPremultiplied,
                       size_t dstTexelSize);
 
-    nsresult DOMElementToImageSurface(dom::Element* imageOrCanvas,
-                                      gfxImageSurface **imageOut,
-                                      WebGLTexelFormat *format);
+    template<class ElementType>
+    nsLayoutUtils::SurfaceFromElementResult SurfaceFromElement(ElementType* aElement) {
+        MOZ_ASSERT(aElement);
+        uint32_t flags =
+            nsLayoutUtils::SFE_WANT_NEW_SURFACE |
+            nsLayoutUtils::SFE_WANT_IMAGE_SURFACE;
+
+        if (mPixelStoreColorspaceConversion == LOCAL_GL_NONE)
+            flags |= nsLayoutUtils::SFE_NO_COLORSPACE_CONVERSION;
+        if (!mPixelStorePremultiplyAlpha)
+            flags |= nsLayoutUtils::SFE_NO_PREMULTIPLY_ALPHA;
+        return nsLayoutUtils::SurfaceFromElement(aElement, flags);
+    }
+
+    nsresult SurfaceFromElementResultToImageSurface(nsLayoutUtils::SurfaceFromElementResult& res,
+                                                    gfxImageSurface **imageOut,
+                                                    WebGLTexelFormat *format);
 
     void CopyTexSubImage2D_base(WebGLenum target,
                                 WebGLint level,
                                 WebGLenum internalformat,
                                 WebGLint xoffset,
                                 WebGLint yoffset,
                                 WebGLint x,
                                 WebGLint y,
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -4318,34 +4318,19 @@ WebGLContext::StencilOpSeparate(WebGLenu
         !ValidateStencilOpEnum(dppass, "stencilOpSeparate: dppass"))
         return;
 
     MakeContextCurrent();
     gl->fStencilOpSeparate(face, sfail, dpfail, dppass);
 }
 
 nsresult
-WebGLContext::DOMElementToImageSurface(Element* imageOrCanvas,
-                                       gfxImageSurface **imageOut, WebGLTexelFormat *format)
-{
-    if (!imageOrCanvas) {
-        return NS_ERROR_FAILURE;
-    }        
-
-    uint32_t flags =
-        nsLayoutUtils::SFE_WANT_NEW_SURFACE |
-        nsLayoutUtils::SFE_WANT_IMAGE_SURFACE;
-
-    if (mPixelStoreColorspaceConversion == LOCAL_GL_NONE)
-        flags |= nsLayoutUtils::SFE_NO_COLORSPACE_CONVERSION;
-    if (!mPixelStorePremultiplyAlpha)
-        flags |= nsLayoutUtils::SFE_NO_PREMULTIPLY_ALPHA;
-
-    nsLayoutUtils::SurfaceFromElementResult res =
-        nsLayoutUtils::SurfaceFromElement(imageOrCanvas, flags);
+WebGLContext::SurfaceFromElementResultToImageSurface(nsLayoutUtils::SurfaceFromElementResult& res,
+                                                     gfxImageSurface **imageOut, WebGLTexelFormat *format)
+{
     if (!res.mSurface)
         return NS_ERROR_FAILURE;
     if (res.mSurface->GetType() != gfxASurface::SurfaceTypeImage) {
         // SurfaceFromElement lied!
         return NS_ERROR_FAILURE;
     }
 
     // We disallow loading cross-domain images and videos that have not been validated
@@ -4364,27 +4349,24 @@ WebGLContext::DOMElementToImageSurface(E
         nsresult rv = HTMLCanvasElement()->NodePrincipal()->Subsumes(res.mPrincipal, &subsumes);
         if (NS_FAILED(rv) || !subsumes) {
             GenerateWarning("It is forbidden to load a WebGL texture from a cross-domain element that has not been validated with CORS. "
                                 "See https://developer.mozilla.org/en/WebGL/Cross-Domain_Textures");
             return NS_ERROR_DOM_SECURITY_ERR;
         }
     }
 
-    // part 2: if the DOM element is a canvas, check that it's not write-only.
-    // That would indicate a tainted canvas, i.e. a canvas that could contain
+    // part 2: if the DOM element is write-only, it might contain
     // cross-domain image data.
-    if (nsHTMLCanvasElement* canvas = nsHTMLCanvasElement::FromContent(imageOrCanvas)) {
-        if (canvas->IsWriteOnly()) {
-            GenerateWarning("The canvas used as source for texImage2D here is tainted (write-only). It is forbidden "
-                                "to load a WebGL texture from a tainted canvas. A Canvas becomes tainted for example "
-                                "when a cross-domain image is drawn on it. "
-                                "See https://developer.mozilla.org/en/WebGL/Cross-Domain_Textures");
-            return NS_ERROR_DOM_SECURITY_ERR;
-        }
+    if (res.mIsWriteOnly) {
+        GenerateWarning("The canvas used as source for texImage2D here is tainted (write-only). It is forbidden "
+                        "to load a WebGL texture from a tainted canvas. A Canvas becomes tainted for example "
+                        "when a cross-domain image is drawn on it. "
+                        "See https://developer.mozilla.org/en/WebGL/Cross-Domain_Textures");
+        return NS_ERROR_DOM_SECURITY_ERR;
     }
 
     // End of security checks, now we should be safe regarding cross-domain images
     // Notice that there is never a need to mark the WebGL canvas as write-only, since we reject write-only/cross-domain
     // texture sources in the first place.
 
     gfxImageSurface* surf = static_cast<gfxImageSurface*>(res.mSurface.get());
 
@@ -5778,42 +5760,16 @@ NS_IMETHODIMP
 WebGLContext::TexImage2D_dom(WebGLenum target, WebGLint level, WebGLenum internalformat,
                              WebGLenum format, GLenum type, Element* elt)
 {
     ErrorResult rv;
     TexImage2D(NULL, target, level, internalformat, format, type, elt, rv);
     return rv.ErrorCode();
 }
 
-void
-WebGLContext::TexImage2D(JSContext* /* unused */, WebGLenum target,
-                         WebGLint level, WebGLenum internalformat,
-                         WebGLenum format, WebGLenum type, Element* elt,
-                         ErrorResult& rv)
-{
-    if (!IsContextStable())
-        return;
-
-    nsRefPtr<gfxImageSurface> isurf;
-
-    WebGLTexelFormat srcFormat;
-    rv = DOMElementToImageSurface(elt, getter_AddRefs(isurf), &srcFormat);
-    if (rv.Failed())
-        return;
-
-    uint32_t byteLength = isurf->Stride() * isurf->Height();
-
-    return TexImage2D_base(target, level, internalformat,
-                           isurf->Width(), isurf->Height(), isurf->Stride(), 0,
-                           format, type,
-                           isurf->Data(), byteLength,
-                           -1,
-                           srcFormat, mPixelStorePremultiplyAlpha);
-}
-
 NS_IMETHODIMP
 WebGLContext::TexSubImage2D(int32_t)
 {
     if (!IsContextStable())
         return NS_OK;
 
     return NS_ERROR_FAILURE;
 }
@@ -6017,43 +5973,16 @@ WebGLContext::TexSubImage2D_dom(WebGLenu
                                 WebGLenum format, WebGLenum type,
                                 Element *elt)
 {
     ErrorResult rv;
     TexSubImage2D(NULL, target, level, xoffset, yoffset, format, type, elt, rv);
     return rv.ErrorCode();
 }
 
-void
-WebGLContext::TexSubImage2D(JSContext* /* unused */, WebGLenum target,
-                            WebGLint level, WebGLint xoffset, WebGLint yoffset,
-                            WebGLenum format, WebGLenum type,
-                            dom::Element* elt, ErrorResult& rv)
-{
-    if (!IsContextStable())
-        return;
-
-    nsRefPtr<gfxImageSurface> isurf;
-
-    WebGLTexelFormat srcFormat;
-    rv = DOMElementToImageSurface(elt, getter_AddRefs(isurf), &srcFormat);
-    if (rv.Failed())
-        return;
-
-    uint32_t byteLength = isurf->Stride() * isurf->Height();
-
-    return TexSubImage2D_base(target, level,
-                              xoffset, yoffset,
-                              isurf->Width(), isurf->Height(), isurf->Stride(),
-                              format, type,
-                              isurf->Data(), byteLength,
-                              -1,
-                              srcFormat, mPixelStorePremultiplyAlpha);
-}
-
 bool
 WebGLContext::LoseContext()
 {
     if (!IsContextStable())
         return false;
 
     ForceLoseContext();
 
--- a/content/html/content/public/nsHTMLCanvasElement.h
+++ b/content/html/content/public/nsHTMLCanvasElement.h
@@ -173,9 +173,15 @@ protected:
 public:
   // Record whether this canvas should be write-only or not.
   // We set this when script paints an image from a different origin.
   // We also transitively set it when script paints a canvas which
   // is itself write-only.
   bool                     mWriteOnly;
 };
 
+inline nsISupports*
+GetISupports(nsHTMLCanvasElement* p)
+{
+  return static_cast<nsGenericElement*>(p);
+}
+
 #endif /* nsHTMLCanvasElement_h__ */
--- a/content/html/content/src/nsHTMLImageElement.cpp
+++ b/content/html/content/src/nsHTMLImageElement.cpp
@@ -1,24 +1,21 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/Util.h"
 
-#include "nsIDOMHTMLImageElement.h"
+#include "nsHTMLImageElement.h"
 #include "nsIDOMEventTarget.h"
-#include "nsGenericHTMLElement.h"
-#include "nsImageLoadingContent.h"
 #include "nsGkAtoms.h"
 #include "nsStyleConsts.h"
 #include "nsPresContext.h"
 #include "nsMappedAttributes.h"
-#include "nsIJSNativeInitializer.h"
 #include "nsSize.h"
 #include "nsIDocument.h"
 #include "nsIDOMDocument.h"
 #include "nsIScriptContext.h"
 #include "nsIURL.h"
 #include "nsIIOService.h"
 #include "nsIServiceManager.h"
 #include "nsNetUtil.h"
@@ -43,112 +40,16 @@
 #include "nsIDOMHTMLMapElement.h"
 #include "nsEventDispatcher.h"
 
 #include "nsLayoutUtils.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
-// XXX nav attrs: suppress
-
-class nsHTMLImageElement : public nsGenericHTMLElement,
-                           public nsImageLoadingContent,
-                           public nsIDOMHTMLImageElement,
-                           public nsIJSNativeInitializer
-{
-public:
-  nsHTMLImageElement(already_AddRefed<nsINodeInfo> aNodeInfo);
-  virtual ~nsHTMLImageElement();
-
-  // nsISupports
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_BASIC(nsGenericHTMLElement::)
-  NS_SCRIPTABLE NS_IMETHOD Click() {
-    return nsGenericHTMLElement::Click();
-  }
-  NS_SCRIPTABLE NS_IMETHOD GetTabIndex(PRInt32* aTabIndex) {
-    return nsGenericHTMLElement::GetTabIndex(aTabIndex);
-  }
-  NS_SCRIPTABLE NS_IMETHOD SetTabIndex(PRInt32 aTabIndex) {
-    return nsGenericHTMLElement::SetTabIndex(aTabIndex);
-  }
-  NS_SCRIPTABLE NS_IMETHOD Focus() {
-    return nsGenericHTMLElement::Focus();
-  }
-  NS_SCRIPTABLE NS_IMETHOD GetDraggable(bool* aDraggable);
-  NS_SCRIPTABLE NS_IMETHOD GetInnerHTML(nsAString& aInnerHTML) {
-    return nsGenericHTMLElement::GetInnerHTML(aInnerHTML);
-  }
-  NS_SCRIPTABLE NS_IMETHOD SetInnerHTML(const nsAString& aInnerHTML) {
-    return nsGenericHTMLElement::SetInnerHTML(aInnerHTML);
-  }
-
-  // nsIDOMHTMLImageElement
-  NS_DECL_NSIDOMHTMLIMAGEELEMENT
-
-  // override from nsImageLoadingContent
-  CORSMode GetCORSMode();
-
-  // nsIJSNativeInitializer
-  NS_IMETHOD Initialize(nsISupports* aOwner, JSContext* aContext,
-                        JSObject* aObj, PRUint32 argc, jsval* argv);
-
-  // nsIContent
-  virtual bool ParseAttribute(PRInt32 aNamespaceID,
-                                nsIAtom* aAttribute,
-                                const nsAString& aValue,
-                                nsAttrValue& aResult);
-  virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
-                                              PRInt32 aModType) const;
-  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
-  virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const;
-
-  virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
-
-  bool IsHTMLFocusable(bool aWithMouse, bool *aIsFocusable, PRInt32 *aTabIndex);
-
-  // SetAttr override.  C++ is stupid, so have to override both
-  // overloaded methods.
-  nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
-                   const nsAString& aValue, bool aNotify)
-  {
-    return SetAttr(aNameSpaceID, aName, nsnull, aValue, aNotify);
-  }
-  virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
-                           nsIAtom* aPrefix, const nsAString& aValue,
-                           bool aNotify);
-  virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
-                             bool aNotify);
-
-  virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
-                              nsIContent* aBindingParent,
-                              bool aCompileEventHandlers);
-
-  virtual nsEventStates IntrinsicState() const;
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
-
-  nsresult CopyInnerTo(nsGenericElement* aDest) const;
-
-  void MaybeLoadImage();
-  virtual nsXPCClassInfo* GetClassInfo();
-  virtual nsIDOMNode* AsDOMNode() { return this; }
-protected:
-  nsIntPoint GetXY();
-  nsSize GetWidthHeight();
-};
-
 nsGenericHTMLElement*
 NS_NewHTMLImageElement(already_AddRefed<nsINodeInfo> aNodeInfo,
                        FromParser aFromParser)
 {
   /*
    * nsHTMLImageElement's will be created without a nsINodeInfo passed in
    * if someone says "var img = new Image();" in JavaScript, in a case like
    * that we request the nsINodeInfo from the document's nodeinfo list.
new file mode 100644
--- /dev/null
+++ b/content/html/content/src/nsHTMLImageElement.h
@@ -0,0 +1,108 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsHTMLImageElement_h
+#define nsHTMLImageElement_h
+
+#include "nsGenericHTMLElement.h"
+#include "nsImageLoadingContent.h"
+#include "nsIDOMHTMLImageElement.h"
+#include "nsIJSNativeInitializer.h"
+
+class nsHTMLImageElement : public nsGenericHTMLElement,
+                           public nsImageLoadingContent,
+                           public nsIDOMHTMLImageElement,
+                           public nsIJSNativeInitializer
+{
+public:
+  nsHTMLImageElement(already_AddRefed<nsINodeInfo> aNodeInfo);
+  virtual ~nsHTMLImageElement();
+
+  // nsISupports
+  NS_DECL_ISUPPORTS_INHERITED
+
+  // nsIDOMNode
+  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+
+  // nsIDOMElement
+  NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
+
+  // nsIDOMHTMLElement
+  NS_FORWARD_NSIDOMHTMLELEMENT_BASIC(nsGenericHTMLElement::)
+  NS_SCRIPTABLE NS_IMETHOD Click() {
+    return nsGenericHTMLElement::Click();
+  }
+  NS_SCRIPTABLE NS_IMETHOD GetTabIndex(PRInt32* aTabIndex) {
+    return nsGenericHTMLElement::GetTabIndex(aTabIndex);
+  }
+  NS_SCRIPTABLE NS_IMETHOD SetTabIndex(PRInt32 aTabIndex) {
+    return nsGenericHTMLElement::SetTabIndex(aTabIndex);
+  }
+  NS_SCRIPTABLE NS_IMETHOD Focus() {
+    return nsGenericHTMLElement::Focus();
+  }
+  NS_SCRIPTABLE NS_IMETHOD GetDraggable(bool* aDraggable);
+  NS_SCRIPTABLE NS_IMETHOD GetInnerHTML(nsAString& aInnerHTML) {
+    return nsGenericHTMLElement::GetInnerHTML(aInnerHTML);
+  }
+  NS_SCRIPTABLE NS_IMETHOD SetInnerHTML(const nsAString& aInnerHTML) {
+    return nsGenericHTMLElement::SetInnerHTML(aInnerHTML);
+  }
+
+  // nsIDOMHTMLImageElement
+  NS_DECL_NSIDOMHTMLIMAGEELEMENT
+
+  // override from nsImageLoadingContent
+  mozilla::CORSMode GetCORSMode();
+
+  // nsIJSNativeInitializer
+  NS_IMETHOD Initialize(nsISupports* aOwner, JSContext* aContext,
+                        JSObject* aObj, PRUint32 argc, jsval* argv);
+
+  // nsIContent
+  virtual bool ParseAttribute(PRInt32 aNamespaceID,
+                                nsIAtom* aAttribute,
+                                const nsAString& aValue,
+                                nsAttrValue& aResult);
+  virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
+                                              PRInt32 aModType) const;
+  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
+  virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const;
+
+  virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
+
+  bool IsHTMLFocusable(bool aWithMouse, bool *aIsFocusable, PRInt32 *aTabIndex);
+
+  // SetAttr override.  C++ is stupid, so have to override both
+  // overloaded methods.
+  nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
+                   const nsAString& aValue, bool aNotify)
+  {
+    return SetAttr(aNameSpaceID, aName, nsnull, aValue, aNotify);
+  }
+  virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
+                           nsIAtom* aPrefix, const nsAString& aValue,
+                           bool aNotify);
+  virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
+                             bool aNotify);
+
+  virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
+                              nsIContent* aBindingParent,
+                              bool aCompileEventHandlers);
+
+  virtual nsEventStates IntrinsicState() const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+
+  nsresult CopyInnerTo(nsGenericElement* aDest) const;
+
+  void MaybeLoadImage();
+  virtual nsXPCClassInfo* GetClassInfo();
+  virtual nsIDOMNode* AsDOMNode() { return this; }
+protected:
+  nsIntPoint GetXY();
+  nsSize GetWidthHeight();
+};
+
+#endif /* nsHTMLImageElement_h */
--- a/dom/base/nsDOMClassInfoID.h
+++ b/dom/base/nsDOMClassInfoID.h
@@ -54,23 +54,34 @@ DOMCI_CASTABLE_INTERFACE(nsGenericHTMLEl
                          _extra)                                              \
 DOMCI_CASTABLE_INTERFACE(nsHTMLDocument, nsIDocument, 7, _extra)              \
 DOMCI_CASTABLE_INTERFACE(nsStyledElement, nsStyledElement, 8, _extra)         \
 DOMCI_CASTABLE_INTERFACE(nsSVGStylableElement, nsIContent, 9, _extra)         \
 DOMCI_CASTABLE_INTERFACE(nsIDOMWebGLRenderingContext,                         \
                          nsIDOMWebGLRenderingContext, 10, _extra)             \
 DOMCI_CASTABLE_INTERFACE(nsIWebGLUniformLocation,                             \
                          nsIWebGLUniformLocation, 11, _extra)                 \
-DOMCI_CASTABLE_INTERFACE(nsIDOMImageData, nsIDOMImageData, 12, _extra)
+DOMCI_CASTABLE_INTERFACE(nsIDOMImageData, nsIDOMImageData, 12, _extra)        \
+DOMCI_CASTABLE_NAMESPACED_INTERFACE(mozilla, WebGLUniformLocation,            \
+                                    nsIWebGLUniformLocation, 13, _extra)
  
 // Make sure all classes mentioned in DOMCI_CASTABLE_INTERFACES
 // have been declared.
+#undef DOMCI_CASTABLE_NAMESPACED_INTERFACE
 #define DOMCI_CASTABLE_INTERFACE(_interface, _u1, _u2, _u3) class _interface;
+#define DOMCI_CASTABLE_NAMESPACED_INTERFACE(ns, className, interface, bit, _extra) \
+  namespace ns {                                                        \
+  class className;                                                      \
+  }
 DOMCI_CASTABLE_INTERFACES(unused)
 #undef DOMCI_CASTABLE_INTERFACE
+#undef DOMCI_CASTABLE_NAMESPACED_INTERFACE
+
+#define DOMCI_CASTABLE_NAMESPACED_INTERFACE(ns, className, interface, bit, _extra) \
+  DOMCI_CASTABLE_INTERFACE(ns::className, interface, bit, _extra)
 
 #ifdef _IMPL_NS_LAYOUT
 
 #define DOMCI_CLASS(_dom_class)                                               \
   extern const PRUint32 kDOMClassInfo_##_dom_class##_interfaces;
 
 #include "nsDOMClassInfoClasses.h"
 
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -164,38 +164,86 @@ DOMInterfaces = {
 },
 {
     'workers': True,
     'nativeType': 'JSObject',
     'headerFile': 'jsapi.h',
     'castable': False
 }],
 
+'WebGLRenderingContext': {
+  'nativeType': 'mozilla::WebGLContext',
+  'prefable': True,
+  'resultNotAddRefed': [ 'canvas', 'getContextAttributes', 'getExtension',
+                         'getAttachedShaders' ],
+  'implicitJSContext': [ 'texImage2D', 'texSubImage2D' ],
+  'infallible': [ 'canvas', 'drawingBufferWidth', 'drawingBufferHeight',
+                  'isContextLost', 'getSupportedExtensions',
+                  'getExtension', 'activeTexture',
+                  'attachShader', 'bindAttribLocation', 'bindBuffer',
+                  'bindFramebuffer', 'bindRenderbuffer', 'bindTexture',
+                  'blendColor', 'blendEquation', 'blendEquationSeparate',
+                  'blendFunc', 'blendFuncSeparate', 'bufferData',
+                  'bufferSubData', 'checkFramebufferStatus',
+                  'clear', 'clearColor', 'clearDepth', 'clearStencil',
+                  'colorMask', 'compileShader', 'compressedTexImage2D',
+                  'compressedTexSubImage2D', 'copyTexImage2D',
+                  'copyTexSubImage2D', 'createBuffer', 'createFramebuffer',
+                  'createProgram', 'createRenderbuffer', 'createShader',
+                  'createTexture', 'cullFace', 'deleteBuffer',
+                  'deleteFramebuffer', 'deleteProgram', 'deleteRenderbuffer',
+                  'deleteShader', 'deleteTexture', 'depthFunc', 'depthMask',
+                  'depthRange', 'detachShader', 'disable',
+                  'disableVertexAttribArray', 'drawArrays', 'drawElements',
+                  'enable', 'enableVertexAttribArray', 'finish', 'flush',
+                  'framebufferRenderbuffer', 'framebufferTexture2D',
+                  'frontFace', 'generateMipmap', 'getActiveAttrib',
+                  'getActiveUniform', 'getAttachedShaders', 'getAttribLocation',
+                  'getBufferParameter', 'getError', 'getProgramParameter',
+                  'getRenderbufferParameter', 'getShaderParameter',
+                  'getShaderPrecisionFormat', 'getShaderSource',
+                  'getTexParameter', 'getUniformLocation',
+                  'getVertexAttribOffset', 'hint', 'isBuffer',
+                  'isEnabled', 'isFramebuffer', 'isProgram', 'isRenderbuffer',
+                  'isShader', 'isTexture', 'lineWidth', 'pixelStorei',
+                  'polygonOffset', 'renderbufferStorage', 'sampleCoverage',
+                  'scissor', 'shaderSource', 'stencilFunc',
+                  'stencilFuncSeparate', 'stencilMask', 'stencilMaskSeparate',
+                  'stencilOp', 'stencilOpSeparate', 'texParameterf',
+                  'texParameteri', 'uniform1f', 'uniform1fv', 'uniform1i',
+                  'uniform1iv', 'uniform2f', 'uniform2fv', 'uniform2i',
+                  'uniform2iv', 'uniform3f', 'uniform3fv', 'uniform3i',
+                  'uniform3iv', 'uniform4f', 'uniform4fv', 'uniform4i',
+                  'uniform4iv', 'uniformMatrix2fv', 'uniformMatrix3fv',
+                  'uniformMatrix4fv', 'useProgram', 'validateProgram',
+                  'vertexAttrib1f', 'vertexAttrib1fv', 'vertexAttrib2f',
+                  'vertexAttrib2fv', 'vertexAttrib3f', 'vertexAttrib3fv',
+                  'vertexAttrib4f', 'vertexAttrib4fv', 'vertexAttribPointer',
+                  'viewport'
+                  ]
+},
+
 'XMLHttpRequest': [
 {
     'nativeType': 'nsXMLHttpRequest',
     'prefable': True,
     'infallible': {
         'all': [
             'readyState', 'withCredentials', 'abort', 'statusText',
             'getAllResponseHeaders', 'overrideMimeType', 'mozBackgroundRequest',
             'multipart', 'channel', 'upload', 'status'
         ],
         'getterOnly': [
             'responseType', 'timeout', 'onreadystatechange'
         ]
     },
-    'implicitJSContext': {
-        'all': [
-            'response', 'getInterface', 'send', 'sendAsBinary'
-        ],
-        'setterOnly': [
-            'onreadystatechange'
-        ]
-    },
+    # XXXbz need a JSContext for send() and sendAsBinary because of
+    # the old nsIVariant-based signatures which actually use it for
+    # typed arrays.  Once those go away, we can nuke this line.
+    'implicitJSContext': [ 'send', 'sendAsBinary' ],
     'resultNotAddRefed': [ 'upload', 'responseXML' ]
 },
 {
     'workers': True,
     'nativeType': 'mozilla::dom::workers::XMLHttpRequest',
     'headerFile': 'mozilla/dom/workers/bindings/XMLHttpRequest.h',
     'infallible': {
         'all': ['readyState', 'statusText' ],
@@ -212,22 +260,16 @@ DOMInterfaces = {
     'concrete': False,
     'prefable': True,
     'infallible': {
         'getterOnly': [
             'onabort', 'onerror', 'onload', 'onloadstart', 'onprogress',
             'ontimeout', 'onloadend'
         ]
     },
-    'implicitJSContext': {
-        'setterOnly': [
-            'onabort', 'onerror', 'onload', 'onloadstart', 'onprogress',
-            'ontimeout', 'onloadend'
-        ]
-    }
 },
 {
     'workers': True,
     'concrete': False,
     'nativeType': 'mozilla::dom::workers::XMLHttpRequestEventTarget',
     'headerFile': 'mozilla/dom/workers/bindings/XMLHttpRequestEventTarget.h'
 }],
 
@@ -271,8 +313,58 @@ DOMInterfaces = {
 'TestExternalInterface' : {
     'nativeType': 'mozilla::dom::TestExternalInterface',
     'headerFile': 'TestBindingHeader.h',
     'register': False,
     'castable': False
 },
 
 }
+
+# These are temporary, until they've been converted to use new DOM bindings
+def addExternalIface(iface, nativeType=None, headerFile=None):
+    if nativeType is None:
+        nativeType = 'nsIDOM' + iface
+    domInterface = {
+        'nativeType': nativeType,
+        'concrete': False,
+        'castable': False
+    }
+    if not headerFile is None:
+        domInterface['headerFile'] = headerFile
+    DOMInterfaces[iface] = domInterface
+
+# If you add one of these, you need to make sure nsDOMQS.h has the relevant
+# macros added for it
+def addExternalHTMLElement(element):
+   nativeElement = 'ns' + element
+   addExternalIface(element, nativeType=nativeElement,
+                    headerFile=nativeElement + '.h')
+
+addExternalHTMLElement('HTMLCanvasElement')
+addExternalHTMLElement('HTMLImageElement')
+addExternalHTMLElement('HTMLVideoElement')
+addExternalIface('ImageData', nativeType='mozilla::dom::ImageData',
+                 headerFile='mozilla/dom/ImageData.h')
+addExternalIface('WebGLActiveInfo', nativeType='mozilla::WebGLActiveInfo',
+                 headerFile='WebGLContext.h')
+addExternalIface('WebGLBuffer', nativeType='mozilla::WebGLBuffer',
+                 headerFile='WebGLContext.h')
+addExternalIface('WebGLContextAttributes', nativeType='JSObject',
+                 headerFile='jsapi.h')
+addExternalIface('WebGLExtension', nativeType='nsIWebGLExtension',
+                 headerFile='WebGLContext.h')
+addExternalIface('WebGLFramebuffer', nativeType='mozilla::WebGLFramebuffer',
+                 headerFile='WebGLContext.h')
+addExternalIface('WebGLProgram', nativeType='mozilla::WebGLProgram',
+                 headerFile='WebGLContext.h')
+addExternalIface('WebGLRenderbuffer', nativeType='mozilla::WebGLRenderbuffer',
+                 headerFile='WebGLContext.h')
+addExternalIface('WebGLShader', nativeType='mozilla::WebGLShader',
+                 headerFile='WebGLContext.h')
+addExternalIface('WebGLShaderPrecisionFormat',
+                 nativeType='mozilla::WebGLShaderPrecisionFormat',
+                 headerFile='WebGLContext.h')
+addExternalIface('WebGLTexture', nativeType='mozilla::WebGLTexture',
+                 headerFile='WebGLContext.h')
+addExternalIface('WebGLUniformLocation',
+                 nativeType='mozilla::WebGLUniformLocation',
+                 headerFile='WebGLContext.h')
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -2069,69 +2069,70 @@ def wrapForType(type, descriptorProvider
     """
     wrap = getWrapTemplateForType(type, descriptorProvider,
                                   templateValues.get('result', 'result'),
                                   templateValues.get('successCode', None))
 
     defaultValues = {'obj': 'obj'}
     return string.Template(wrap).substitute(defaultValues, **templateValues)
 
-# Returns a tuple consisting of a CGThing containing the type of the return
-# value and a boolean signalling whether we need to pass a JSContext as the
-# first argument of the call.
+def typeNeedsCx(type):
+    return (type is not None and
+            (type.isCallback() or type.isAny() or type.isObject()))
+
+# Returns a CGThing containing the type of the return value, or None
+# if there is no need for a return value.
 def getRetvalDeclarationForType(returnType, descriptorProvider,
                                 resultAlreadyAddRefed):
     if returnType is None or returnType.isVoid():
         # Nothing to declare
-        return None, False
+        return None
     if returnType.isPrimitive() and returnType.tag() in builtinNames:
         result = CGGeneric(builtinNames[returnType.tag()])
         if returnType.nullable():
             result = CGWrapper(result, pre="Nullable<", post=">")
-        return result, False
+        return result
     if returnType.isString():
-        return CGGeneric("nsString"), False
+        return CGGeneric("nsString")
     if returnType.isEnum():
         if returnType.nullable():
             raise TypeError("We don't support nullable enum return values")
-        return CGGeneric(returnType.inner.identifier.name), False
+        return CGGeneric(returnType.inner.identifier.name)
     if returnType.isGeckoInterface():
         result = CGGeneric(descriptorProvider.getDescriptor(
             returnType.unroll().inner.identifier.name).nativeType)
         if resultAlreadyAddRefed:
             result = CGWrapper(result, pre="nsRefPtr<", post=">")
         else:
             result = CGWrapper(result, post="*")
-        return result, False
+        return result
     if returnType.isCallback():
         # XXXbz we're going to assume that callback types are always
         # nullable for now.
-        return CGGeneric("JSObject*"), False
-    if returnType.tag() is IDLType.Tags.any:
-        return CGGeneric("JS::Value"), False
+        return CGGeneric("JSObject*")
+    if returnType.isAny():
+        return CGGeneric("JS::Value")
     if returnType.isObject():
-        return CGGeneric("JSObject*"), True
+        return CGGeneric("JSObject*")
     if returnType.isSequence():
         nullable = returnType.nullable()
         if nullable:
             returnType = returnType.inner
         # If our result is already addrefed, use the right type in the
         # sequence argument here.
-        (result, needsCx) = getRetvalDeclarationForType(returnType.inner,
-                                                        descriptorProvider,
-                                                        resultAlreadyAddRefed)
+        result = getRetvalDeclarationForType(returnType.inner,
+                                             descriptorProvider,
+                                             resultAlreadyAddRefed)
         result = CGWrapper(result, pre="nsTArray< ", post=" >")
         if nullable:
             result = CGWrapper(result, pre="Nullable< ", post=" >")
-        return result, needsCx
+        return result
     raise TypeError("Don't know how to declare return value for %s" %
                     returnType)
 
-
-
 def isResultAlreadyAddRefed(descriptor, extendedAttributes):
     # Default to already_AddRefed on the main thread, raw pointer in workers
     return not descriptor.workers and not 'resultNotAddRefed' in extendedAttributes
 
 class CGCallGenerator(CGThing):
     """
     A class to generate an actual call to a C++ object.  Assumes that the C++
     object is stored in a variable named "self".
@@ -2154,25 +2155,24 @@ class CGCallGenerator(CGThing):
         # Return values that go in outparams go here
         if resultOutParam:
             args.append(CGGeneric("result"))
         if isFallible:
             args.append(CGGeneric("rv"))
 
         resultAlreadyAddRefed = isResultAlreadyAddRefed(descriptorProvider,
                                                         extendedAttributes)
-        (result, needsCx) = getRetvalDeclarationForType(returnType,
-                                                        descriptorProvider,
-                                                        resultAlreadyAddRefed)
-
-        if not needsCx:
-            needsCx = reduce(lambda b, a: b or a.type.isObject(), arguments,
-                             False)
-
-        if not "cx" in argsPre and (needsCx or 'implicitJSContext' in extendedAttributes):
+        result = getRetvalDeclarationForType(returnType,
+                                             descriptorProvider,
+                                             resultAlreadyAddRefed)
+        needsCx = (typeNeedsCx(returnType) or
+                   any(typeNeedsCx(a.type) for a in arguments) or
+                   'implicitJSContext' in extendedAttributes)
+
+        if not "cx" in argsPre and needsCx:
             args.prepend(CGGeneric("cx"))
 
         # Build up our actual call
         self.cgRoot = CGList([], "\n")
 
         call = CGGeneric(nativeMethodName)
         if static:
             call = CGWrapper(call, pre="%s::" % (descriptorProvider.getDescriptor(
@@ -2428,19 +2428,21 @@ class CGMethodCall(CGThing):
                 firstSigType = possibleSignatures[0][1][idx].type
                 for sigIdx in range(1, len(possibleSignatures)):
                     if possibleSignatures[sigIdx][1][idx].type != firstSigType:
                         raise TypeError(("Signatures with %d arguments for " +
                                          descriptor.interface.identifier.name +
                                          "." + method.identifier.name +
                                          " have different types at index %d" +
                                          " which is before distinguishing" +
-                                         " index %d") % (argCount,
-                                                         idx,
-                                                         distinguishingIndex))
+                                         " index %d.  Types are %s and %s") %
+                                        (argCount, idx,
+                                         distinguishingIndex,
+                                         str(possibleSignatures[sigIdx][1][idx].type),
+                                         str(firstSigType)))
 
             # Convert all our arguments up to the distinguishing index.
             # Doesn't matter which of the possible signatures we use, since
             # they all have the same types up to that point; just use
             # possibleSignatures[0]
             caseBody = [CGGeneric("JS::Value* argv_start = JS_ARGV(cx, vp);")]
             caseBody.extend([ CGArgumentConverter(possibleSignatures[0][1][i],
                                                   i, "argv_start", "argc",
@@ -3397,17 +3399,19 @@ class CGBindingRoot(CGThing):
         descriptors = config.getDescriptors(webIDLFile=webIDLFile,
                                             hasInterfaceOrInterfacePrototypeObject=True)
 
         forwardDeclares = [CGClassForwardDeclare('XPCWrappedNativeScope')]
 
         for x in descriptors:
             nativeType = x.nativeType
             components = x.nativeType.split('::')
-            declare = CGClassForwardDeclare(components[-1])
+            className = components[-1]
+            # JSObject is a struct, not a class
+            declare = CGClassForwardDeclare(className, className is "JSObject")
             if len(components) > 1:
                 declare = CGNamespace.build(components[:-1],
                                             CGWrapper(declare, declarePre='\n',
                                                       declarePost='\n'),
                                             declareOnly=True)
             forwardDeclares.append(CGWrapper(declare, declarePost='\n'))
 
         forwardDeclares = CGList(forwardDeclares)
@@ -3459,17 +3463,20 @@ class CGBindingRoot(CGThing):
                           'mozilla/dom/DOMJSClass.h'],
                          ['mozilla/dom/Nullable.h',
                           'mozilla/dom/PrimitiveConversions.h',
                           'XPCQuickStubs.h',
                           'nsDOMQS.h',
                           'AccessCheck.h',
                           'WorkerPrivate.h',
                           'nsContentUtils.h',
-                          'mozilla/Preferences.h'
+                          'mozilla/Preferences.h',
+                          # Have to include nsDOMQS.h to get fast arg unwrapping
+                          # for old-binding things with castability.
+                          'nsDOMQS.h'
                           ],
                          curr)
 
         # Add include guards.
         curr = CGIncludeGuard(prefix, curr)
 
         # Add the auto-generated comment.
         curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT)
--- a/dom/bindings/Makefile.in
+++ b/dom/bindings/Makefile.in
@@ -66,17 +66,18 @@ EXPORTS_$(binding_include_path) = \
   Nullable.h \
   PrimitiveConversions.h \
   TypedArray.h \
   BindingUtils.h \
   $(exported_binding_headers) \
   $(NULL)
 
 LOCAL_INCLUDES += -I$(topsrcdir)/js/xpconnect/src \
-  -I$(topsrcdir)/js/xpconnect/wrappers
+  -I$(topsrcdir)/js/xpconnect/wrappers \
+  -I$(topsrcdir)/content/html/content/src
 
 include $(topsrcdir)/config/rules.mk
 
 # If you change bindinggen_dependencies here, change it in
 # dom/bindings/test/Makefile.in too.
 bindinggen_dependencies := \
   BindingGen.py \
   Bindings.conf \
--- a/dom/bindings/test/TestBindingHeader.h
+++ b/dom/bindings/test/TestBindingHeader.h
@@ -241,28 +241,31 @@ public:
   void PassOptionalNullableStringWithDefaultValue(const nsAString&, ErrorResult&);
 
   // Enumarated types
   void PassEnum(TestEnum, ErrorResult&);
   void PassOptionalEnum(const Optional<TestEnum>&, ErrorResult&);
   TestEnum ReceiveEnum(ErrorResult&);
 
   // Callback types
-  void PassCallback(JSObject*, ErrorResult&);
-  void PassNullableCallback(JSObject*, ErrorResult&);
-  void PassOptionalCallback(const Optional<JSObject*>&, ErrorResult&);
-  void PassOptionalNullableCallback(const Optional<JSObject*>&, ErrorResult&);
-  void PassOptionalNullableCallbackWithDefaultValue(JSObject*, ErrorResult&);
-  JSObject* ReceiveCallback(ErrorResult&);
-  JSObject* ReceiveNullableCallback(ErrorResult&);
+  void PassCallback(JSContext*, JSObject*, ErrorResult&);
+  void PassNullableCallback(JSContext*, JSObject*, ErrorResult&);
+  void PassOptionalCallback(JSContext*, const Optional<JSObject*>&,
+                            ErrorResult&);
+  void PassOptionalNullableCallback(JSContext*, const Optional<JSObject*>&,
+                                    ErrorResult&);
+  void PassOptionalNullableCallbackWithDefaultValue(JSContext*, JSObject*,
+                                                    ErrorResult&);
+  JSObject* ReceiveCallback(JSContext*, ErrorResult&);
+  JSObject* ReceiveNullableCallback(JSContext*, ErrorResult&);
 
   // Any types
-  void PassAny(JS::Value, ErrorResult&);
-  void PassOptionalAny(const Optional<JS::Value>&, ErrorResult&);
-  JS::Value ReceiveAny(ErrorResult&);
+  void PassAny(JSContext*, JS::Value, ErrorResult&);
+  void PassOptionalAny(JSContext*, const Optional<JS::Value>&, ErrorResult&);
+  JS::Value ReceiveAny(JSContext*, ErrorResult&);
 
   void PassObject(JSContext*, JSObject&, ErrorResult&);
   void PassNullableObject(JSContext*, JSObject*, ErrorResult&);
   void PassOptionalObject(JSContext*, const Optional<NonNull<JSObject> >&, ErrorResult&);
   void PassOptionalNullableObject(JSContext*, const Optional<JSObject*>&, ErrorResult&);
   void PassOptionalNullableObjectWithDefaultValue(JSContext*, JSObject*, ErrorResult&);
   JSObject* ReceiveObject(JSContext*, ErrorResult&);
   JSObject* ReceiveNullableObject(JSContext*, ErrorResult&);
@@ -384,18 +387,18 @@ private:
   void PassOptionalSequence(Optional<Sequence<int32_t> >&, ErrorResult&) MOZ_DELETE;
   void PassOptionalNullableSequence(Optional<Nullable<Sequence<int32_t> > >&,
                                     ErrorResult&) MOZ_DELETE;
   void PassOptionalObjectSequence(Optional<Sequence<OwningNonNull<TestInterface> > >&,
                                   ErrorResult&) MOZ_DELETE;
   void PassOptionalArrayBuffer(Optional<ArrayBuffer>&, ErrorResult&) MOZ_DELETE;
   void PassOptionalNullableArrayBuffer(Optional<ArrayBuffer*>&, ErrorResult&) MOZ_DELETE;
   void PassOptionalEnum(Optional<TestEnum>&, ErrorResult&) MOZ_DELETE;
-  void PassOptionalCallback(Optional<JSObject*>&, ErrorResult&) MOZ_DELETE;
-  void PassOptionalNullableCallback(Optional<JSObject*>&, ErrorResult&) MOZ_DELETE;
+  void PassOptionalCallback(JSContext*, Optional<JSObject*>&, ErrorResult&) MOZ_DELETE;
+  void PassOptionalNullableCallback(JSContext*, Optional<JSObject*>&, ErrorResult&) MOZ_DELETE;
   void PassOptionalAny(Optional<JS::Value>&, ErrorResult) MOZ_DELETE;
 
   // And test that string stuff is always const
   void PassString(nsAString&, ErrorResult&) MOZ_DELETE;
   void PassNullableString(nsAString&, ErrorResult&) MOZ_DELETE;
   void PassOptionalString(Optional<nsAString>&, ErrorResult&) MOZ_DELETE;
   void PassOptionalNullableString(Optional<nsAString>&, ErrorResult&) MOZ_DELETE;
   void PassOptionalNullableStringWithDefaultValue(nsAString&, ErrorResult&) MOZ_DELETE;
new file mode 100644
--- /dev/null
+++ b/dom/webidl/WebGLRenderingContext.webidl
@@ -0,0 +1,722 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * The origin of this IDL file is
+ * https://www.khronos.org/registry/webgl/specs/latest/webgl.idl
+ *
+ * Copyright © 2012 Khronos Group
+ */
+
+ // AUTOGENERATED FILE -- DO NOT EDIT -- SEE Makefile
+//
+// WebGL IDL definitions scraped from the Khronos specification:
+// https://www.khronos.org/registry/webgl/specs/latest/
+//
+// This IDL depends on the typed array specification defined at:
+// https://www.khronos.org/registry/typedarray/specs/latest/typedarrays.idl
+
+// XXXbz all sorts of forward declarations for things that are not new
+// bindings yet.
+interface Event;
+interface HTMLCanvasElement;
+interface HTMLImageElement;
+interface HTMLVideoElement;
+interface ImageData;
+interface WebGLContextAttributes;
+/*dictionary WebGLContextAttributes {
+    boolean alpha = true;
+    boolean depth = true;
+    boolean stencil = false;
+    boolean antialias = true;
+    boolean premultipliedAlpha = true;
+    boolean preserveDrawingBuffer = false;
+    };*/
+
+interface WebGLExtension;
+
+interface WebGLBuffer;
+
+interface WebGLFramebuffer;
+
+interface WebGLProgram;
+
+interface WebGLRenderbuffer;
+
+interface WebGLShader;
+
+interface WebGLTexture;
+
+interface WebGLUniformLocation;
+
+interface WebGLActiveInfo;
+
+interface WebGLShaderPrecisionFormat;
+
+interface WebGLRenderingContext {
+
+    /* ClearBufferMask */
+    const unsigned long DEPTH_BUFFER_BIT               = 0x00000100;
+    const unsigned long STENCIL_BUFFER_BIT             = 0x00000400;
+    const unsigned long COLOR_BUFFER_BIT               = 0x00004000;
+    
+    /* BeginMode */
+    const unsigned long POINTS                         = 0x0000;
+    const unsigned long LINES                          = 0x0001;
+    const unsigned long LINE_LOOP                      = 0x0002;
+    const unsigned long LINE_STRIP                     = 0x0003;
+    const unsigned long TRIANGLES                      = 0x0004;
+    const unsigned long TRIANGLE_STRIP                 = 0x0005;
+    const unsigned long TRIANGLE_FAN                   = 0x0006;
+    
+    /* AlphaFunction (not supported in ES20) */
+    /*      NEVER */
+    /*      LESS */
+    /*      EQUAL */
+    /*      LEQUAL */
+    /*      GREATER */
+    /*      NOTEQUAL */
+    /*      GEQUAL */
+    /*      ALWAYS */
+    
+    /* BlendingFactorDest */
+    const unsigned long ZERO                           = 0;
+    const unsigned long ONE                            = 1;
+    const unsigned long SRC_COLOR                      = 0x0300;
+    const unsigned long ONE_MINUS_SRC_COLOR            = 0x0301;
+    const unsigned long SRC_ALPHA                      = 0x0302;
+    const unsigned long ONE_MINUS_SRC_ALPHA            = 0x0303;
+    const unsigned long DST_ALPHA                      = 0x0304;
+    const unsigned long ONE_MINUS_DST_ALPHA            = 0x0305;
+    
+    /* BlendingFactorSrc */
+    /*      ZERO */
+    /*      ONE */
+    const unsigned long DST_COLOR                      = 0x0306;
+    const unsigned long ONE_MINUS_DST_COLOR            = 0x0307;
+    const unsigned long SRC_ALPHA_SATURATE             = 0x0308;
+    /*      SRC_ALPHA */
+    /*      ONE_MINUS_SRC_ALPHA */
+    /*      DST_ALPHA */
+    /*      ONE_MINUS_DST_ALPHA */
+    
+    /* BlendEquationSeparate */
+    const unsigned long FUNC_ADD                       = 0x8006;
+    const unsigned long BLEND_EQUATION                 = 0x8009;
+    const unsigned long BLEND_EQUATION_RGB             = 0x8009;   /* same as BLEND_EQUATION */
+    const unsigned long BLEND_EQUATION_ALPHA           = 0x883D;
+    
+    /* BlendSubtract */
+    const unsigned long FUNC_SUBTRACT                  = 0x800A;
+    const unsigned long FUNC_REVERSE_SUBTRACT          = 0x800B;
+    
+    /* Separate Blend Functions */
+    const unsigned long BLEND_DST_RGB                  = 0x80C8;
+    const unsigned long BLEND_SRC_RGB                  = 0x80C9;
+    const unsigned long BLEND_DST_ALPHA                = 0x80CA;
+    const unsigned long BLEND_SRC_ALPHA                = 0x80CB;
+    const unsigned long CONSTANT_COLOR                 = 0x8001;
+    const unsigned long ONE_MINUS_CONSTANT_COLOR       = 0x8002;
+    const unsigned long CONSTANT_ALPHA                 = 0x8003;
+    const unsigned long ONE_MINUS_CONSTANT_ALPHA       = 0x8004;
+    const unsigned long BLEND_COLOR                    = 0x8005;
+    
+    /* Buffer Objects */
+    const unsigned long ARRAY_BUFFER                   = 0x8892;
+    const unsigned long ELEMENT_ARRAY_BUFFER           = 0x8893;
+    const unsigned long ARRAY_BUFFER_BINDING           = 0x8894;
+    const unsigned long ELEMENT_ARRAY_BUFFER_BINDING   = 0x8895;
+    
+    const unsigned long STREAM_DRAW                    = 0x88E0;
+    const unsigned long STATIC_DRAW                    = 0x88E4;
+    const unsigned long DYNAMIC_DRAW                   = 0x88E8;
+    
+    const unsigned long BUFFER_SIZE                    = 0x8764;
+    const unsigned long BUFFER_USAGE                   = 0x8765;
+    
+    const unsigned long CURRENT_VERTEX_ATTRIB          = 0x8626;
+    
+    /* CullFaceMode */
+    const unsigned long FRONT                          = 0x0404;
+    const unsigned long BACK                           = 0x0405;
+    const unsigned long FRONT_AND_BACK                 = 0x0408;
+    
+    /* DepthFunction */
+    /*      NEVER */
+    /*      LESS */
+    /*      EQUAL */
+    /*      LEQUAL */
+    /*      GREATER */
+    /*      NOTEQUAL */
+    /*      GEQUAL */
+    /*      ALWAYS */
+    
+    /* EnableCap */
+    /* TEXTURE_2D */
+    const unsigned long CULL_FACE                      = 0x0B44;
+    const unsigned long BLEND                          = 0x0BE2;
+    const unsigned long DITHER                         = 0x0BD0;
+    const unsigned long STENCIL_TEST                   = 0x0B90;
+    const unsigned long DEPTH_TEST                     = 0x0B71;
+    const unsigned long SCISSOR_TEST                   = 0x0C11;
+    const unsigned long POLYGON_OFFSET_FILL            = 0x8037;
+    const unsigned long SAMPLE_ALPHA_TO_COVERAGE       = 0x809E;
+    const unsigned long SAMPLE_COVERAGE                = 0x80A0;
+    
+    /* ErrorCode */
+    const unsigned long NO_ERROR                       = 0;
+    const unsigned long INVALID_ENUM                   = 0x0500;
+    const unsigned long INVALID_VALUE                  = 0x0501;
+    const unsigned long INVALID_OPERATION              = 0x0502;
+    const unsigned long OUT_OF_MEMORY                  = 0x0505;
+    
+    /* FrontFaceDirection */
+    const unsigned long CW                             = 0x0900;
+    const unsigned long CCW                            = 0x0901;
+    
+    /* GetPName */
+    const unsigned long LINE_WIDTH                     = 0x0B21;
+    const unsigned long ALIASED_POINT_SIZE_RANGE       = 0x846D;
+    const unsigned long ALIASED_LINE_WIDTH_RANGE       = 0x846E;
+    const unsigned long CULL_FACE_MODE                 = 0x0B45;
+    const unsigned long FRONT_FACE                     = 0x0B46;
+    const unsigned long DEPTH_RANGE                    = 0x0B70;
+    const unsigned long DEPTH_WRITEMASK                = 0x0B72;
+    const unsigned long DEPTH_CLEAR_VALUE              = 0x0B73;
+    const unsigned long DEPTH_FUNC                     = 0x0B74;
+    const unsigned long STENCIL_CLEAR_VALUE            = 0x0B91;
+    const unsigned long STENCIL_FUNC                   = 0x0B92;
+    const unsigned long STENCIL_FAIL                   = 0x0B94;
+    const unsigned long STENCIL_PASS_DEPTH_FAIL        = 0x0B95;
+    const unsigned long STENCIL_PASS_DEPTH_PASS        = 0x0B96;
+    const unsigned long STENCIL_REF                    = 0x0B97;
+    const unsigned long STENCIL_VALUE_MASK             = 0x0B93;
+    const unsigned long STENCIL_WRITEMASK              = 0x0B98;
+    const unsigned long STENCIL_BACK_FUNC              = 0x8800;
+    const unsigned long STENCIL_BACK_FAIL              = 0x8801;
+    const unsigned long STENCIL_BACK_PASS_DEPTH_FAIL   = 0x8802;
+    const unsigned long STENCIL_BACK_PASS_DEPTH_PASS   = 0x8803;
+    const unsigned long STENCIL_BACK_REF               = 0x8CA3;
+    const unsigned long STENCIL_BACK_VALUE_MASK        = 0x8CA4;
+    const unsigned long STENCIL_BACK_WRITEMASK         = 0x8CA5;
+    const unsigned long VIEWPORT                       = 0x0BA2;
+    const unsigned long SCISSOR_BOX                    = 0x0C10;
+    /*      SCISSOR_TEST */
+    const unsigned long COLOR_CLEAR_VALUE              = 0x0C22;
+    const unsigned long COLOR_WRITEMASK                = 0x0C23;
+    const unsigned long UNPACK_ALIGNMENT               = 0x0CF5;
+    const unsigned long PACK_ALIGNMENT                 = 0x0D05;
+    const unsigned long MAX_TEXTURE_SIZE               = 0x0D33;
+    const unsigned long MAX_VIEWPORT_DIMS              = 0x0D3A;
+    const unsigned long SUBPIXEL_BITS                  = 0x0D50;
+    const unsigned long RED_BITS                       = 0x0D52;
+    const unsigned long GREEN_BITS                     = 0x0D53;
+    const unsigned long BLUE_BITS                      = 0x0D54;
+    const unsigned long ALPHA_BITS                     = 0x0D55;
+    const unsigned long DEPTH_BITS                     = 0x0D56;
+    const unsigned long STENCIL_BITS                   = 0x0D57;
+    const unsigned long POLYGON_OFFSET_UNITS           = 0x2A00;
+    /*      POLYGON_OFFSET_FILL */
+    const unsigned long POLYGON_OFFSET_FACTOR          = 0x8038;
+    const unsigned long TEXTURE_BINDING_2D             = 0x8069;
+    const unsigned long SAMPLE_BUFFERS                 = 0x80A8;
+    const unsigned long SAMPLES                        = 0x80A9;
+    const unsigned long SAMPLE_COVERAGE_VALUE          = 0x80AA;
+    const unsigned long SAMPLE_COVERAGE_INVERT         = 0x80AB;
+    
+    /* GetTextureParameter */
+    /*      TEXTURE_MAG_FILTER */
+    /*      TEXTURE_MIN_FILTER */
+    /*      TEXTURE_WRAP_S */
+    /*      TEXTURE_WRAP_T */
+    
+    const unsigned long COMPRESSED_TEXTURE_FORMATS     = 0x86A3;
+    
+    /* HintMode */
+    const unsigned long DONT_CARE                      = 0x1100;
+    const unsigned long FASTEST                        = 0x1101;
+    const unsigned long NICEST                         = 0x1102;
+    
+    /* HintTarget */
+    const unsigned long GENERATE_MIPMAP_HINT            = 0x8192;
+    
+    /* DataType */
+    const unsigned long BYTE                           = 0x1400;
+    const unsigned long UNSIGNED_BYTE                  = 0x1401;
+    const unsigned long SHORT                          = 0x1402;
+    const unsigned long UNSIGNED_SHORT                 = 0x1403;
+    const unsigned long INT                            = 0x1404;
+    const unsigned long UNSIGNED_INT                   = 0x1405;
+    const unsigned long FLOAT                          = 0x1406;
+    
+    /* PixelFormat */
+    const unsigned long DEPTH_COMPONENT                = 0x1902;
+    const unsigned long ALPHA                          = 0x1906;
+    const unsigned long RGB                            = 0x1907;
+    const unsigned long RGBA                           = 0x1908;
+    const unsigned long LUMINANCE                      = 0x1909;
+    const unsigned long LUMINANCE_ALPHA                = 0x190A;
+    
+    /* PixelType */
+    /*      UNSIGNED_BYTE */
+    const unsigned long UNSIGNED_SHORT_4_4_4_4         = 0x8033;
+    const unsigned long UNSIGNED_SHORT_5_5_5_1         = 0x8034;
+    const unsigned long UNSIGNED_SHORT_5_6_5           = 0x8363;
+    
+    /* Shaders */
+    const unsigned long FRAGMENT_SHADER                  = 0x8B30;
+    const unsigned long VERTEX_SHADER                    = 0x8B31;
+    const unsigned long MAX_VERTEX_ATTRIBS               = 0x8869;
+    const unsigned long MAX_VERTEX_UNIFORM_VECTORS       = 0x8DFB;
+    const unsigned long MAX_VARYING_VECTORS              = 0x8DFC;
+    const unsigned long MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8B4D;
+    const unsigned long MAX_VERTEX_TEXTURE_IMAGE_UNITS   = 0x8B4C;
+    const unsigned long MAX_TEXTURE_IMAGE_UNITS          = 0x8872;
+    const unsigned long MAX_FRAGMENT_UNIFORM_VECTORS     = 0x8DFD;
+    const unsigned long SHADER_TYPE                      = 0x8B4F;
+    const unsigned long DELETE_STATUS                    = 0x8B80;
+    const unsigned long LINK_STATUS                      = 0x8B82;
+    const unsigned long VALIDATE_STATUS                  = 0x8B83;
+    const unsigned long ATTACHED_SHADERS                 = 0x8B85;
+    const unsigned long ACTIVE_UNIFORMS                  = 0x8B86;
+    const unsigned long ACTIVE_ATTRIBUTES                = 0x8B89;
+    const unsigned long SHADING_LANGUAGE_VERSION         = 0x8B8C;
+    const unsigned long CURRENT_PROGRAM                  = 0x8B8D;
+    
+    /* StencilFunction */
+    const unsigned long NEVER                          = 0x0200;
+    const unsigned long LESS                           = 0x0201;
+    const unsigned long EQUAL                          = 0x0202;
+    const unsigned long LEQUAL                         = 0x0203;
+    const unsigned long GREATER                        = 0x0204;
+    const unsigned long NOTEQUAL                       = 0x0205;
+    const unsigned long GEQUAL                         = 0x0206;
+    const unsigned long ALWAYS                         = 0x0207;
+    
+    /* StencilOp */
+    /*      ZERO */
+    const unsigned long KEEP                           = 0x1E00;
+    const unsigned long REPLACE                        = 0x1E01;
+    const unsigned long INCR                           = 0x1E02;
+    const unsigned long DECR                           = 0x1E03;
+    const unsigned long INVERT                         = 0x150A;
+    const unsigned long INCR_WRAP                      = 0x8507;
+    const unsigned long DECR_WRAP                      = 0x8508;
+    
+    /* StringName */
+    const unsigned long VENDOR                         = 0x1F00;
+    const unsigned long RENDERER                       = 0x1F01;
+    const unsigned long VERSION                        = 0x1F02;
+    
+    /* TextureMagFilter */
+    const unsigned long NEAREST                        = 0x2600;
+    const unsigned long LINEAR                         = 0x2601;
+    
+    /* TextureMinFilter */
+    /*      NEAREST */
+    /*      LINEAR */
+    const unsigned long NEAREST_MIPMAP_NEAREST         = 0x2700;
+    const unsigned long LINEAR_MIPMAP_NEAREST          = 0x2701;
+    const unsigned long NEAREST_MIPMAP_LINEAR          = 0x2702;
+    const unsigned long LINEAR_MIPMAP_LINEAR           = 0x2703;
+    
+    /* TextureParameterName */
+    const unsigned long TEXTURE_MAG_FILTER             = 0x2800;
+    const unsigned long TEXTURE_MIN_FILTER             = 0x2801;
+    const unsigned long TEXTURE_WRAP_S                 = 0x2802;
+    const unsigned long TEXTURE_WRAP_T                 = 0x2803;
+    
+    /* TextureTarget */
+    const unsigned long TEXTURE_2D                     = 0x0DE1;
+    const unsigned long TEXTURE                        = 0x1702;
+    
+    const unsigned long TEXTURE_CUBE_MAP               = 0x8513;
+    const unsigned long TEXTURE_BINDING_CUBE_MAP       = 0x8514;
+    const unsigned long TEXTURE_CUBE_MAP_POSITIVE_X    = 0x8515;
+    const unsigned long TEXTURE_CUBE_MAP_NEGATIVE_X    = 0x8516;
+    const unsigned long TEXTURE_CUBE_MAP_POSITIVE_Y    = 0x8517;
+    const unsigned long TEXTURE_CUBE_MAP_NEGATIVE_Y    = 0x8518;
+    const unsigned long TEXTURE_CUBE_MAP_POSITIVE_Z    = 0x8519;
+    const unsigned long TEXTURE_CUBE_MAP_NEGATIVE_Z    = 0x851A;
+    const unsigned long MAX_CUBE_MAP_TEXTURE_SIZE      = 0x851C;
+    
+    /* TextureUnit */
+    const unsigned long TEXTURE0                       = 0x84C0;
+    const unsigned long TEXTURE1                       = 0x84C1;
+    const unsigned long TEXTURE2                       = 0x84C2;
+    const unsigned long TEXTURE3                       = 0x84C3;
+    const unsigned long TEXTURE4                       = 0x84C4;
+    const unsigned long TEXTURE5                       = 0x84C5;
+    const unsigned long TEXTURE6                       = 0x84C6;
+    const unsigned long TEXTURE7                       = 0x84C7;
+    const unsigned long TEXTURE8                       = 0x84C8;
+    const unsigned long TEXTURE9                       = 0x84C9;
+    const unsigned long TEXTURE10                      = 0x84CA;
+    const unsigned long TEXTURE11                      = 0x84CB;
+    const unsigned long TEXTURE12                      = 0x84CC;
+    const unsigned long TEXTURE13                      = 0x84CD;
+    const unsigned long TEXTURE14                      = 0x84CE;
+    const unsigned long TEXTURE15                      = 0x84CF;
+    const unsigned long TEXTURE16                      = 0x84D0;
+    const unsigned long TEXTURE17                      = 0x84D1;
+    const unsigned long TEXTURE18                      = 0x84D2;
+    const unsigned long TEXTURE19                      = 0x84D3;
+    const unsigned long TEXTURE20                      = 0x84D4;
+    const unsigned long TEXTURE21                      = 0x84D5;
+    const unsigned long TEXTURE22                      = 0x84D6;
+    const unsigned long TEXTURE23                      = 0x84D7;
+    const unsigned long TEXTURE24                      = 0x84D8;
+    const unsigned long TEXTURE25                      = 0x84D9;
+    const unsigned long TEXTURE26                      = 0x84DA;
+    const unsigned long TEXTURE27                      = 0x84DB;
+    const unsigned long TEXTURE28                      = 0x84DC;
+    const unsigned long TEXTURE29                      = 0x84DD;
+    const unsigned long TEXTURE30                      = 0x84DE;
+    const unsigned long TEXTURE31                      = 0x84DF;
+    const unsigned long ACTIVE_TEXTURE                 = 0x84E0;
+    
+    /* TextureWrapMode */
+    const unsigned long REPEAT                         = 0x2901;
+    const unsigned long CLAMP_TO_EDGE                  = 0x812F;
+    const unsigned long MIRRORED_REPEAT                = 0x8370;
+    
+    /* Uniform Types */
+    const unsigned long FLOAT_VEC2                     = 0x8B50;
+    const unsigned long FLOAT_VEC3                     = 0x8B51;
+    const unsigned long FLOAT_VEC4                     = 0x8B52;
+    const unsigned long INT_VEC2                       = 0x8B53;
+    const unsigned long INT_VEC3                       = 0x8B54;
+    const unsigned long INT_VEC4                       = 0x8B55;
+    const unsigned long BOOL                           = 0x8B56;
+    const unsigned long BOOL_VEC2                      = 0x8B57;
+    const unsigned long BOOL_VEC3                      = 0x8B58;
+    const unsigned long BOOL_VEC4                      = 0x8B59;
+    const unsigned long FLOAT_MAT2                     = 0x8B5A;
+    const unsigned long FLOAT_MAT3                     = 0x8B5B;
+    const unsigned long FLOAT_MAT4                     = 0x8B5C;
+    const unsigned long SAMPLER_2D                     = 0x8B5E;
+    const unsigned long SAMPLER_CUBE                   = 0x8B60;
+    
+    /* Vertex Arrays */
+    const unsigned long VERTEX_ATTRIB_ARRAY_ENABLED        = 0x8622;
+    const unsigned long VERTEX_ATTRIB_ARRAY_SIZE           = 0x8623;
+    const unsigned long VERTEX_ATTRIB_ARRAY_STRIDE         = 0x8624;
+    const unsigned long VERTEX_ATTRIB_ARRAY_TYPE           = 0x8625;
+    const unsigned long VERTEX_ATTRIB_ARRAY_NORMALIZED     = 0x886A;
+    const unsigned long VERTEX_ATTRIB_ARRAY_POINTER        = 0x8645;
+    const unsigned long VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = 0x889F;
+    
+    /* Shader Source */
+    const unsigned long COMPILE_STATUS                 = 0x8B81;
+    
+    /* Shader Precision-Specified Types */
+    const unsigned long LOW_FLOAT                      = 0x8DF0;
+    const unsigned long MEDIUM_FLOAT                   = 0x8DF1;
+    const unsigned long HIGH_FLOAT                     = 0x8DF2;
+    const unsigned long LOW_INT                        = 0x8DF3;
+    const unsigned long MEDIUM_INT                     = 0x8DF4;
+    const unsigned long HIGH_INT                       = 0x8DF5;
+    
+    /* Framebuffer Object. */
+    const unsigned long FRAMEBUFFER                    = 0x8D40;
+    const unsigned long RENDERBUFFER                   = 0x8D41;
+    
+    const unsigned long RGBA4                          = 0x8056;
+    const unsigned long RGB5_A1                        = 0x8057;
+    const unsigned long RGB565                         = 0x8D62;
+    const unsigned long DEPTH_COMPONENT16              = 0x81A5;
+    const unsigned long STENCIL_INDEX                  = 0x1901;
+    const unsigned long STENCIL_INDEX8                 = 0x8D48;
+    const unsigned long DEPTH_STENCIL                  = 0x84F9;
+    
+    const unsigned long RENDERBUFFER_WIDTH             = 0x8D42;
+    const unsigned long RENDERBUFFER_HEIGHT            = 0x8D43;
+    const unsigned long RENDERBUFFER_INTERNAL_FORMAT   = 0x8D44;
+    const unsigned long RENDERBUFFER_RED_SIZE          = 0x8D50;
+    const unsigned long RENDERBUFFER_GREEN_SIZE        = 0x8D51;
+    const unsigned long RENDERBUFFER_BLUE_SIZE         = 0x8D52;
+    const unsigned long RENDERBUFFER_ALPHA_SIZE        = 0x8D53;
+    const unsigned long RENDERBUFFER_DEPTH_SIZE        = 0x8D54;
+    const unsigned long RENDERBUFFER_STENCIL_SIZE      = 0x8D55;
+    
+    const unsigned long FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE           = 0x8CD0;
+    const unsigned long FRAMEBUFFER_ATTACHMENT_OBJECT_NAME           = 0x8CD1;
+    const unsigned long FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL         = 0x8CD2;
+    const unsigned long FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE = 0x8CD3;
+    
+    const unsigned long COLOR_ATTACHMENT0              = 0x8CE0;
+    const unsigned long DEPTH_ATTACHMENT               = 0x8D00;
+    const unsigned long STENCIL_ATTACHMENT             = 0x8D20;
+    const unsigned long DEPTH_STENCIL_ATTACHMENT       = 0x821A;
+    
+    const unsigned long NONE                           = 0;
+    
+    const unsigned long FRAMEBUFFER_COMPLETE                      = 0x8CD5;
+    const unsigned long FRAMEBUFFER_INCOMPLETE_ATTACHMENT         = 0x8CD6;
+    const unsigned long FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = 0x8CD7;
+    const unsigned long FRAMEBUFFER_INCOMPLETE_DIMENSIONS         = 0x8CD9;
+    const unsigned long FRAMEBUFFER_UNSUPPORTED                   = 0x8CDD;
+    
+    const unsigned long FRAMEBUFFER_BINDING            = 0x8CA6;
+    const unsigned long RENDERBUFFER_BINDING           = 0x8CA7;
+    const unsigned long MAX_RENDERBUFFER_SIZE          = 0x84E8;
+    
+    const unsigned long INVALID_FRAMEBUFFER_OPERATION  = 0x0506;
+    
+    /* WebGL-specific enums */
+    const unsigned long UNPACK_FLIP_Y_WEBGL            = 0x9240;
+    const unsigned long UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241;
+    const unsigned long CONTEXT_LOST_WEBGL             = 0x9242;
+    const unsigned long UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243;
+    const unsigned long BROWSER_DEFAULT_WEBGL          = 0x9244;
+
+    readonly attribute HTMLCanvasElement canvas;
+    readonly attribute long drawingBufferWidth;
+    readonly attribute long drawingBufferHeight;
+
+    [WebGLHandlesContextLoss] WebGLContextAttributes getContextAttributes();
+    [WebGLHandlesContextLoss] boolean isContextLost();
+    
+    sequence<DOMString>? getSupportedExtensions();
+    // XXXbz In the spec, this is "object?"; I'm making it
+    // WebGLExtension? just for ease of implementation.
+    WebGLExtension? getExtension(DOMString name);
+
+    void activeTexture(unsigned long texture);
+    void attachShader(WebGLProgram? program, WebGLShader? shader);
+    void bindAttribLocation(WebGLProgram? program, unsigned long index, DOMString name);
+    void bindBuffer(unsigned long target, WebGLBuffer? buffer);
+    void bindFramebuffer(unsigned long target, WebGLFramebuffer? framebuffer);
+    void bindRenderbuffer(unsigned long target, WebGLRenderbuffer? renderbuffer);
+    void bindTexture(unsigned long target, WebGLTexture? texture);
+    void blendColor(float red, float green, float blue, float alpha);
+    void blendEquation(unsigned long mode);
+    void blendEquationSeparate(unsigned long modeRGB, unsigned long modeAlpha);
+    void blendFunc(unsigned long sfactor, unsigned long dfactor);
+    void blendFuncSeparate(unsigned long srcRGB, unsigned long dstRGB, 
+                           unsigned long srcAlpha, unsigned long dstAlpha);
+
+    void bufferData(unsigned long target, long long size, unsigned long usage);
+    void bufferData(unsigned long target, ArrayBufferView data, unsigned long usage);
+    void bufferData(unsigned long target, ArrayBuffer? data, unsigned long usage);
+    void bufferSubData(unsigned long target, long long offset, ArrayBufferView data);
+    void bufferSubData(unsigned long target, long long offset, ArrayBuffer? data);
+
+    [WebGLHandlesContextLoss] unsigned long checkFramebufferStatus(unsigned long target);
+    void clear(unsigned long mask);
+    void clearColor(float red, float green, float blue, float alpha);
+    void clearDepth(float depth);
+    void clearStencil(long s);
+    void colorMask(boolean red, boolean green, boolean blue, boolean alpha);
+    void compileShader(WebGLShader? shader);
+
+    void compressedTexImage2D(unsigned long target, long level, unsigned long internalformat,
+                              long width, long height, long border,
+                              ArrayBufferView data);
+    void compressedTexSubImage2D(unsigned long target, long level,
+                                 long xoffset, long yoffset,
+                                 long width, long height, unsigned long format,
+                                 ArrayBufferView data);
+
+    void copyTexImage2D(unsigned long target, long level, unsigned long internalformat, 
+                        long x, long y, long width, long height, 
+                        long border);
+    void copyTexSubImage2D(unsigned long target, long level, long xoffset, long yoffset, 
+                           long x, long y, long width, long height);
+
+    WebGLBuffer? createBuffer();
+    WebGLFramebuffer? createFramebuffer();
+    WebGLProgram? createProgram();
+    WebGLRenderbuffer? createRenderbuffer();
+    WebGLShader? createShader(unsigned long type);
+    WebGLTexture? createTexture();
+
+    void cullFace(unsigned long mode);
+
+    void deleteBuffer(WebGLBuffer? buffer);
+    void deleteFramebuffer(WebGLFramebuffer? framebuffer);
+    void deleteProgram(WebGLProgram? program);
+    void deleteRenderbuffer(WebGLRenderbuffer? renderbuffer);
+    void deleteShader(WebGLShader? shader);
+    void deleteTexture(WebGLTexture? texture);
+
+    void depthFunc(unsigned long func);
+    void depthMask(boolean flag);
+    void depthRange(float zNear, float zFar);
+    void detachShader(WebGLProgram? program, WebGLShader? shader);
+    void disable(unsigned long cap);
+    void disableVertexAttribArray(unsigned long index);
+    void drawArrays(unsigned long mode, long first, long count);
+    void drawElements(unsigned long mode, long count, unsigned long type, long long offset);
+
+    void enable(unsigned long cap);
+    void enableVertexAttribArray(unsigned long index);
+    void finish();
+    void flush();
+    void framebufferRenderbuffer(unsigned long target, unsigned long attachment, 
+                                 unsigned long renderbuffertarget, 
+                                 WebGLRenderbuffer? renderbuffer);
+    void framebufferTexture2D(unsigned long target, unsigned long attachment, unsigned long textarget, 
+                              WebGLTexture? texture, long level);
+    void frontFace(unsigned long mode);
+
+    void generateMipmap(unsigned long target);
+
+    WebGLActiveInfo? getActiveAttrib(WebGLProgram? program, unsigned long index);
+    WebGLActiveInfo? getActiveUniform(WebGLProgram? program, unsigned long index);
+    sequence<WebGLShader>? getAttachedShaders(WebGLProgram? program);
+
+    [WebGLHandlesContextLoss] long getAttribLocation(WebGLProgram? program, DOMString name);
+
+    any getBufferParameter(unsigned long target, unsigned long pname);
+    any getParameter(unsigned long pname);
+
+    [WebGLHandlesContextLoss] unsigned long getError();
+
+    any getFramebufferAttachmentParameter(unsigned long target, unsigned long attachment, 
+                                          unsigned long pname);
+    any getProgramParameter(WebGLProgram? program, unsigned long pname);
+    DOMString? getProgramInfoLog(WebGLProgram? program);
+    any getRenderbufferParameter(unsigned long target, unsigned long pname);
+    any getShaderParameter(WebGLShader? shader, unsigned long pname);
+    WebGLShaderPrecisionFormat? getShaderPrecisionFormat(unsigned long shadertype, unsigned long precisiontype);
+    DOMString? getShaderInfoLog(WebGLShader? shader);
+
+    DOMString? getShaderSource(WebGLShader? shader);
+
+    any getTexParameter(unsigned long target, unsigned long pname);
+
+    any getUniform(WebGLProgram? program, WebGLUniformLocation? location);
+
+    WebGLUniformLocation? getUniformLocation(WebGLProgram? program, DOMString name);
+
+    any getVertexAttrib(unsigned long index, unsigned long pname);
+
+    [WebGLHandlesContextLoss] long long getVertexAttribOffset(unsigned long index, unsigned long pname);
+
+    void hint(unsigned long target, unsigned long mode);
+    [WebGLHandlesContextLoss] boolean isBuffer(WebGLBuffer? buffer);
+    [WebGLHandlesContextLoss] boolean isEnabled(unsigned long cap);
+    [WebGLHandlesContextLoss] boolean isFramebuffer(WebGLFramebuffer? framebuffer);
+    [WebGLHandlesContextLoss] boolean isProgram(WebGLProgram? program);
+    [WebGLHandlesContextLoss] boolean isRenderbuffer(WebGLRenderbuffer? renderbuffer);
+    [WebGLHandlesContextLoss] boolean isShader(WebGLShader? shader);
+    [WebGLHandlesContextLoss] boolean isTexture(WebGLTexture? texture);
+    void lineWidth(float width);
+    void linkProgram(WebGLProgram? program);
+    void pixelStorei(unsigned long pname, long param);
+    void polygonOffset(float factor, float units);
+
+    void readPixels(long x, long y, long width, long height, 
+                    unsigned long format, unsigned long type, ArrayBufferView? pixels);
+
+    void renderbufferStorage(unsigned long target, unsigned long internalformat, 
+                             long width, long height);
+    void sampleCoverage(float value, boolean invert);
+    void scissor(long x, long y, long width, long height);
+
+    void shaderSource(WebGLShader? shader, DOMString source);
+
+    void stencilFunc(unsigned long func, long ref, unsigned long mask);
+    void stencilFuncSeparate(unsigned long face, unsigned long func, long ref, unsigned long mask);
+    void stencilMask(unsigned long mask);
+    void stencilMaskSeparate(unsigned long face, unsigned long mask);
+    void stencilOp(unsigned long fail, unsigned long zfail, unsigned long zpass);
+    void stencilOpSeparate(unsigned long face, unsigned long fail, unsigned long zfail, unsigned long zpass);
+
+    void texImage2D(unsigned long target, long level, unsigned long internalformat, 
+                    long width, long height, long border, unsigned long format, 
+                    unsigned long type, ArrayBufferView? pixels);
+    void texImage2D(unsigned long target, long level, unsigned long internalformat,
+                    unsigned long format, unsigned long type, ImageData? pixels);
+    void texImage2D(unsigned long target, long level, unsigned long internalformat,
+                    unsigned long format, unsigned long type, HTMLImageElement image); // May throw DOMException
+    void texImage2D(unsigned long target, long level, unsigned long internalformat,
+                    unsigned long format, unsigned long type, HTMLCanvasElement canvas); // May throw DOMException
+    void texImage2D(unsigned long target, long level, unsigned long internalformat,
+                    unsigned long format, unsigned long type, HTMLVideoElement video); // May throw DOMException
+
+    void texParameterf(unsigned long target, unsigned long pname, float param);
+    void texParameteri(unsigned long target, unsigned long pname, long param);
+
+    void texSubImage2D(unsigned long target, long level, long xoffset, long yoffset, 
+                       long width, long height, 
+                       unsigned long format, unsigned long type, ArrayBufferView? pixels);
+    void texSubImage2D(unsigned long target, long level, long xoffset, long yoffset, 
+                       unsigned long format, unsigned long type, ImageData? pixels);
+    void texSubImage2D(unsigned long target, long level, long xoffset, long yoffset, 
+                       unsigned long format, unsigned long type, HTMLImageElement image); // May throw DOMException
+    void texSubImage2D(unsigned long target, long level, long xoffset, long yoffset, 
+                       unsigned long format, unsigned long type, HTMLCanvasElement canvas); // May throw DOMException
+    void texSubImage2D(unsigned long target, long level, long xoffset, long yoffset, 
+                       unsigned long format, unsigned long type, HTMLVideoElement video); // May throw DOMException
+
+    void uniform1f(WebGLUniformLocation? location, float x);
+    void uniform1fv(WebGLUniformLocation? location, Float32Array v);
+    void uniform1fv(WebGLUniformLocation? location, sequence<float> v);
+    void uniform1i(WebGLUniformLocation? location, long x);
+    void uniform1iv(WebGLUniformLocation? location, Int32Array v);
+    void uniform1iv(WebGLUniformLocation? location, sequence<long> v);
+    void uniform2f(WebGLUniformLocation? location, float x, float y);
+    void uniform2fv(WebGLUniformLocation? location, Float32Array v);
+    void uniform2fv(WebGLUniformLocation? location, sequence<float> v);
+    void uniform2i(WebGLUniformLocation? location, long x, long y);
+    void uniform2iv(WebGLUniformLocation? location, Int32Array v);
+    void uniform2iv(WebGLUniformLocation? location, sequence<long> v);
+    void uniform3f(WebGLUniformLocation? location, float x, float y, float z);
+    void uniform3fv(WebGLUniformLocation? location, Float32Array v);
+    void uniform3fv(WebGLUniformLocation? location, sequence<float> v);
+    void uniform3i(WebGLUniformLocation? location, long x, long y, long z);
+    void uniform3iv(WebGLUniformLocation? location, Int32Array v);
+    void uniform3iv(WebGLUniformLocation? location, sequence<long> v);
+    void uniform4f(WebGLUniformLocation? location, float x, float y, float z, float w);
+    void uniform4fv(WebGLUniformLocation? location, Float32Array v);
+    void uniform4fv(WebGLUniformLocation? location, sequence<float> v);
+    void uniform4i(WebGLUniformLocation? location, long x, long y, long z, long w);
+    void uniform4iv(WebGLUniformLocation? location, Int32Array v);
+    void uniform4iv(WebGLUniformLocation? location, sequence<long> v);
+
+    void uniformMatrix2fv(WebGLUniformLocation? location, boolean transpose, 
+                          Float32Array value);
+    void uniformMatrix2fv(WebGLUniformLocation? location, boolean transpose, 
+                          sequence<float> value);
+    void uniformMatrix3fv(WebGLUniformLocation? location, boolean transpose, 
+                          Float32Array value);
+    void uniformMatrix3fv(WebGLUniformLocation? location, boolean transpose, 
+                          sequence<float> value);
+    void uniformMatrix4fv(WebGLUniformLocation? location, boolean transpose, 
+                          Float32Array value);
+    void uniformMatrix4fv(WebGLUniformLocation? location, boolean transpose, 
+                          sequence<float> value);
+
+    void useProgram(WebGLProgram? program);
+    void validateProgram(WebGLProgram? program);
+
+    void vertexAttrib1f(unsigned long indx, float x);
+    void vertexAttrib1fv(unsigned long indx, Float32Array values);
+    void vertexAttrib1fv(unsigned long indx, sequence<float> values);
+    void vertexAttrib2f(unsigned long indx, float x, float y);
+    void vertexAttrib2fv(unsigned long indx, Float32Array values);
+    void vertexAttrib2fv(unsigned long indx, sequence<float> values);
+    void vertexAttrib3f(unsigned long indx, float x, float y, float z);
+    void vertexAttrib3fv(unsigned long indx, Float32Array values);
+    void vertexAttrib3fv(unsigned long indx, sequence<float> values);
+    void vertexAttrib4f(unsigned long indx, float x, float y, float z, float w);
+    void vertexAttrib4fv(unsigned long indx, Float32Array values);
+    void vertexAttrib4fv(unsigned long indx, sequence<float> values);
+    void vertexAttribPointer(unsigned long indx, long size, unsigned long type, 
+                             boolean normalized, long stride, long long offset);
+
+    void viewport(long x, long y, long width, long height);
+};
+
+/*[Constructor(DOMString type, optional WebGLContextEventInit eventInit)]
+interface WebGLContextEvent : Event {
+    readonly attribute DOMString statusMessage;
+    };*/
+
+// EventInit is defined in the DOM4 specification.
+/*dictionary WebGLContextEventInit : EventInit {
+    DOMString statusMessage;
+    };*/
--- a/dom/webidl/WebIDL.mk
+++ b/dom/webidl/WebIDL.mk
@@ -6,16 +6,17 @@ webidl_base = $(topsrcdir)/dom/webidl
 
 webidl_files = \
   Function.webidl \
   EventListener.webidl \
   EventTarget.webidl \
   XMLHttpRequest.webidl \
   XMLHttpRequestEventTarget.webidl \
   XMLHttpRequestUpload.webidl \
+  WebGLRenderingContext.webidl \
   $(NULL)
 
 ifdef ENABLE_TESTS
 test_webidl_files := TestCodeGen.webidl
 else
 test_webidl_files := $(NULL)
 endif
 
--- a/dom/workers/XMLHttpRequest.cpp
+++ b/dom/workers/XMLHttpRequest.cpp
@@ -2153,17 +2153,17 @@ XMLHttpRequest::SetResponseType(XMLHttpR
 
   nsString acceptedResponseTypeString;
   runnable->GetResponseType(acceptedResponseTypeString);
 
   mResponseType = ConvertStringToResponseType(acceptedResponseTypeString);
 }
 
 jsval
-XMLHttpRequest::GetResponse(ErrorResult& aRv)
+XMLHttpRequest::GetResponse(JSContext* /* unused */, ErrorResult& aRv)
 {
   if (NS_SUCCEEDED(mStateData.mResponseTextResult) &&
       JSVAL_IS_VOID(mStateData.mResponse)) {
     MOZ_ASSERT(mStateData.mResponseText.Length());
     MOZ_ASSERT(NS_SUCCEEDED(mStateData.mResponseResult));
 
     JSString* str =
       JS_NewUCStringCopyN(GetJSContext(), mStateData.mResponseText.get(),
--- a/dom/workers/XMLHttpRequest.h
+++ b/dom/workers/XMLHttpRequest.h
@@ -75,23 +75,23 @@ public:
   void
   Unpin();
 
   bool
   Notify(JSContext* aCx, Status aStatus) MOZ_OVERRIDE;
 
 #define IMPL_GETTER_AND_SETTER(_type)                                          \
   JSObject*                                                                    \
-  GetOn##_type(ErrorResult& aRv)                                               \
+  GetOn##_type(JSContext* /* unused */, ErrorResult& aRv)                      \
   {                                                                            \
     return GetEventListener(NS_LITERAL_STRING(#_type), aRv);                   \
   }                                                                            \
                                                                                \
   void                                                                         \
-  SetOn##_type(JSObject* aListener, ErrorResult& aRv)                          \
+  SetOn##_type(JSContext* /* unused */, JSObject* aListener, ErrorResult& aRv) \
   {                                                                            \
     SetEventListener(NS_LITERAL_STRING(#_type), aListener, aRv);               \
   }
 
   IMPL_GETTER_AND_SETTER(readystatechange)
 
 #undef IMPL_GETTER_AND_SETTER
 
@@ -197,17 +197,17 @@ public:
   {
     return mResponseType;
   }
 
   void
   SetResponseType(XMLHttpRequestResponseType aResponseType, ErrorResult& aRv);
 
   jsval
-  GetResponse(ErrorResult& aRv);
+  GetResponse(JSContext* /* unused */, ErrorResult& aRv);
 
   void
   GetResponseText(nsAString& aResponseText, ErrorResult& aRv);
 
   JSObject*
   GetResponseXML() const
   {
     return NULL;
@@ -215,17 +215,17 @@ public:
 
   JSObject*
   GetChannel() const
   {
     return NULL;
   }
 
   JS::Value
-  GetInterface(JSObject* aIID, ErrorResult& aRv)
+  GetInterface(JSContext* cx, JSObject* aIID, ErrorResult& aRv)
   {
     aRv.Throw(NS_ERROR_FAILURE);
     return JSVAL_NULL;
   }
 
   XMLHttpRequestUpload*
   GetUploadObjectNoCreate() const
   {
--- a/dom/workers/XMLHttpRequestEventTarget.h
+++ b/dom/workers/XMLHttpRequestEventTarget.h
@@ -24,23 +24,23 @@ public:
   virtual void
   _trace(JSTracer* aTrc) MOZ_OVERRIDE;
 
   virtual void
   _finalize(JSFreeOp* aFop) MOZ_OVERRIDE;
 
 #define IMPL_GETTER_AND_SETTER(_type)                                          \
   JSObject*                                                                    \
-  GetOn##_type(ErrorResult& aRv)                                               \
+  GetOn##_type(JSContext* /* unused */, ErrorResult& aRv)                      \
   {                                                                            \
     return GetEventListener(NS_LITERAL_STRING(#_type), aRv);                   \
   }                                                                            \
                                                                                \
   void                                                                         \
-  SetOn##_type(JSObject* aListener, ErrorResult& aRv)                          \
+  SetOn##_type(JSContext* /* unused */, JSObject* aListener, ErrorResult& aRv) \
   {                                                                            \
     SetEventListener(NS_LITERAL_STRING(#_type), aListener, aRv);               \
   }
 
   IMPL_GETTER_AND_SETTER(loadstart)
   IMPL_GETTER_AND_SETTER(progress)
   IMPL_GETTER_AND_SETTER(abort)
   IMPL_GETTER_AND_SETTER(error)
--- a/js/xpconnect/src/nsDOMQS.h
+++ b/js/xpconnect/src/nsDOMQS.h
@@ -3,20 +3,27 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsDOMQS_h__
 #define nsDOMQS_h__
 
 #include "mozilla/dom/ImageData.h"
 #include "nsDOMClassInfoID.h"
 #include "nsGenericHTMLElement.h"
+#include "nsHTMLCanvasElement.h"
+#include "nsHTMLImageElement.h"
+#include "nsHTMLVideoElement.h"
 #include "nsHTMLDocument.h"
 #include "nsICSSDeclaration.h"
 #include "nsIDOMWebGLRenderingContext.h"
 #include "nsSVGStylableElement.h"
+#include "WebGLContext.h"
+// WebGLContext pulls in windows.h, which defines random crap, so nuke
+// those defines.
+#include "qsWinUndefs.h"
 
 #define DEFINE_UNWRAP_CAST(_interface, _base, _bit)                           \
 template <>                                                                   \
 inline JSBool                                                                 \
 xpc_qsUnwrapThis<_interface>(JSContext *cx,                                   \
                              JSObject *obj,                                   \
                              _interface **ppThis,                             \
                              nsISupports **pThisRef,                          \
@@ -168,27 +175,37 @@ xpc_qsUnwrapArg<_clazz>(JSContext *cx, j
                         _clazz **ppArgRef, jsval *vp)                         \
 {                                                                             \
     nsISupports* argRef;                                                      \
     nsresult rv = xpc_qsUnwrapArg<_clazz>(cx, v, ppArg, &argRef, vp);         \
     *ppArgRef = static_cast<_clazz*>(static_cast<nsIContent*>(argRef));       \
     return rv;                                                                \
 }
 
+DEFINE_UNWRAP_CAST_HTML(canvas, nsHTMLCanvasElement)
+DEFINE_UNWRAP_CAST_HTML(img, nsHTMLImageElement)
+DEFINE_UNWRAP_CAST_HTML(video, nsHTMLVideoElement)
+
 inline nsISupports*
 ToSupports(nsContentList *p)
 {
     return static_cast<nsINodeList*>(p);
 }
 
 inline nsISupports*
 ToCanonicalSupports(nsINode* p)
 {
     return p;
 }
 
 inline nsISupports*
+ToSupports(nsINode* p)
+{
+  return p;
+}
+
+inline nsISupports*
 ToCanonicalSupports(nsContentList *p)
 {
     return static_cast<nsINodeList*>(p);
 }
 
 #endif /* nsDOMQS_h__ */
--- a/js/xpconnect/src/qsWinUndefs.h
+++ b/js/xpconnect/src/qsWinUndefs.h
@@ -1,8 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // Undefines for stupid windows macros
 #ifdef GetClassName
 #undef GetClassName
 #endif
+#ifdef CreateEvent
+#undef CreateEvent
+#endif
+#ifdef GetBinaryType
+#undef GetBinaryType
+#endif